1 unit gtk3boxes;
2 
3 interface
4 
5 uses
6   // LazUtils
7   UITypes,
8   // LCL
9   LCLType, LCLStrConsts,LCLProc, InterfaceBase,
10   LazGtk3, LazGLib2, LazGObject2, LazGdk3, gtk3objects;
11 
12 
13 type
functionnull14   TBtnListfunction=function(ndx:integer):longint of object;
15 
16   { TGtk3DialogFactory }
17 
18   TGtk3DialogFactory = class
19     btn_def: PGtkButton;
20     DefaultNdx: Integer;
21     fButtons: TDialogButtons;
22     pButtons: PLongint;
23     fCaption: string;
24     fDialogType:longint;
25     Dialog: PGtkDialog;
26     DialogResult: Integer;
27     constructor CreateAsk(const DialogCaption, DialogMessage: string;
28        DialogType: LongInt; Buttons: TDialogButtons; HelpCtx: Longint);
29     constructor CreatePrompt(const DialogCaption, DialogMessage: string;
30        DialogType: LongInt; Buttons: PLongInt;
31        ButtonCount: LongInt; DefaultIndex: LongInt; EscapeResult: LongInt);
32     constructor CreateMsgBox(hWnd: HWND; lpText, lpCaption: PChar;
33        uType: Cardinal);
34     constructor CreateMsgBox1(hWnd: HWND; lpText, lpCaption: PChar;
35        uType: Cardinal);
trnull36     class function tr(UseWidgetStr: boolean; const TranslatedStr, WidgetStr: String): string;
37     destructor Destroy;override;
38     procedure run;
btn_coll_infonull39     function btn_coll_info(ndx:integer):longint;
btn_ptr_infonull40     function btn_ptr_info(ndx:integer):longint;
41     procedure set_message_text(const msg:string;const is_pango_markup:boolean=false);
42     procedure update_widget_list(const func:TBtnListFunction);
43     procedure CreateButton(const ALabel : String; const AResponse: Integer;
44       const AImageHint: Integer = -1);
lcl_resultnull45     function lcl_result:integer;
btn_resultnull46     function btn_result:integer;
ResponseIDnull47     class function ResponseID(const AnID: Integer): Integer;
gtk_resp_to_lclnull48     class function gtk_resp_to_lcl(const gtk_resp:integer):integer;
gtk_resp_to_btnnull49     class function gtk_resp_to_btn(const gtk_resp:integer):integer;
MessageTypenull50     class function MessageType(ADialogType:longint):TGtkMessageType;
51   end;
52 
53 
54 implementation
55 
56 // fake GTK button responses
57 const
58   GTK_RESPONSE_LCL_ALL = -10;
59   GTK_RESPONSE_LCL_YESTOALL = -3; // GTK_RESPONSE_ACCEPT;
60   GTK_RESPONSE_LCL_RETRY = -12;
61   GTK_RESPONSE_LCL_IGNORE = -13;
62   GTK_RESPONSE_LCL_NOTOALL = -14;
63 
64 
65 { callbacks }
BoxClosednull66 function BoxClosed(Widget : PGtkWidget; {%H-}Event : PGdkEvent;
67   data: gPointer) : GBoolean; cdecl;
68 var
69   ModalResult : PtrUInt;
70 begin
71   { We were requested by window manager to close so return EscapeResult}
72   if PInteger(data)^ = 0 then
73   begin
74     ModalResult:= {%H-}PtrUInt(g_object_get_data(PGObject(Widget), 'modal_result'));
75     { Don't allow to close if we don't have a default return value }
76     Result:= (ModalResult = 0);
77     if Result then
78       DebugLn('Do not close !!!')
79     else
80       PInteger(data)^:= Integer(ModalResult);
81   end else
82     Result:= false;
83 end;
84 
ButtonClickednull85 function ButtonClicked(Widget : PGtkWidget; data: gPointer) : GBoolean; cdecl;
86 var
87   ModalResult : PtrUInt;
88 begin
89   ModalResult := {%H-}PtrUInt(g_object_get_data(PGObject(Widget), 'modal_result'));
90   PInteger(data)^ := Integer(ModalResult);
91   Result := False;
92 end;
93 
94 
TGtk3DialogFactory.ResponseIDnull95 class function TGtk3DialogFactory.ResponseID(const AnID: Integer): Integer;
96 begin
97   case AnID of
98     idButtonOK       : Result := GTK_RESPONSE_OK;
99     idButtonCancel   : Result := GTK_RESPONSE_CANCEL;
100     idButtonHelp     : Result := GTK_RESPONSE_HELP;
101     idButtonYes      : Result := GTK_RESPONSE_YES;
102     idButtonNo       : Result := GTK_RESPONSE_NO;
103     idButtonClose    : Result := GTK_RESPONSE_CLOSE;
104     idButtonAbort    : Result := GTK_RESPONSE_REJECT;
105     idButtonRetry    : Result := GTK_RESPONSE_LCL_RETRY;
106     idButtonIgnore   : Result := GTK_RESPONSE_LCL_IGNORE;
107     idButtonAll      : Result := GTK_RESPONSE_LCL_ALL;
108     idButtonNoToAll  : Result := GTK_RESPONSE_LCL_NOTOALL;
109     idButtonYesToAll : Result := GTK_RESPONSE_LCL_YESTOALL;
110   else
111     Result:=AnID;
112   end;
113 end;
114 
TGtk3DialogFactory.gtk_resp_to_lclnull115 class function TGtk3DialogFactory.gtk_resp_to_lcl(const gtk_resp:integer):integer;
116 begin
117   case gtk_resp of
118   GTK_RESPONSE_OK: Result:=ID_OK;
119   GTK_RESPONSE_CANCEL: Result:=id_Cancel;
120   GTK_RESPONSE_CLOSE: Result:=id_Close;
121   GTK_RESPONSE_YES: Result:=id_Yes;
122   GTK_RESPONSE_NO: Result:=id_No;
123 
124   GTK_RESPONSE_NONE: Result:=0;
125   GTK_RESPONSE_REJECT: Result:=id_abort;
126   GTK_RESPONSE_ACCEPT: Result:=id_Yes;
127 
128   GTK_RESPONSE_LCL_RETRY: Result:=id_Retry;
129   GTK_RESPONSE_LCL_IGNORE:  Result:=id_Ignore;
130   GTK_RESPONSE_LCL_ALL:  Result:=idButtonAll;
131   GTK_RESPONSE_LCL_NOTOALL: Result:=idButtonNoToAll;
132   //GTK_RESPONSE_LCL_YESTOALL: Result:= idButtonYesToAll;
133   else
134     Result:=gtk_resp;
135   end;
136 end;
137 
TGtk3DialogFactory.gtk_resp_to_btnnull138 class function TGtk3DialogFactory.gtk_resp_to_btn(const gtk_resp:integer):integer;
139 begin
140   case gtk_resp of
141   -5{GTK_RESPONSE_OK}: Result:=  idButtonOk;
142   -6{GTK_RESPONSE_CANCEL}:  Result := idButtonCancel;
143   -7{GTK_RESPONSE_CLOSE}: Result:=idButtonClose;
144   -8{GTK_RESPONSE_YES}: Result:=idButtonYes;
145   -9{GTK_RESPONSE_NO}: Result:=idButtonNo;
146 
147   -1{GTK_RESPONSE_NONE}: Result:=0;
148   -2{GTK_RESPONSE_REJECT}: Result:=idButtonAbort;
149   -3{GTK_RESPONSE_ACCEPT}: Result:=idButtonYesToAll;
150 
151   GTK_RESPONSE_LCL_RETRY: Result:=idButtonRetry;
152   GTK_RESPONSE_LCL_IGNORE:  Result:=idButtonIgnore;
153   GTK_RESPONSE_LCL_ALL:  Result:=idButtonAll;
154   GTK_RESPONSE_LCL_NOTOALL: Result:=idButtonNoToAll;
155   //GTK_RESPONSE_LCL_YESTOALL: Result:= idButtonYesToAll;
156   else
157     Result:=gtk_resp;
158   end;
159 end;
160 
161 procedure TGtk3DialogFactory.CreateButton(
162     const ALabel : String;
163     const AResponse: Integer;
164     const AImageHint: Integer = -1);
165 var
166   NewButton: PGtkWidget;
167   //BitmapHandle, MaskHandle: HBitmap;
168   // GDIObject: PGDIObject;
169   //Pixbuf: PGdkPixbuf;
170   // Mask: PGdkBitmap;
171   //Img: PGtkWidget;
172 begin
173 
174   NewButton := gtk_dialog_add_button(Dialog,
175     PgChar(ReplaceAmpersandsWithUnderscores(ALabel)), AResponse);
176   gtk_button_set_use_underline(PGtkButton(NewButton), True);
177   g_object_set_data(PGObject(NewButton), 'modal_result',
178         {%H-}Pointer(PtrInt(AResponse)));
179   (*
180   if AImageHint >= 0 then
181   begin
182     if ThemeServices.GetStockImage(AImageHint, BitmapHandle, MaskHandle) then
183     begin
184       GDIObject := {%H-}PGDIObject(BitmapHandle);
185       Mask := nil;
186       Pixbuf := nil;
187       if GDIObject^.GDIBitmapType = gbPixbuf then
188         Pixbuf := GDIObject^.GDIPixbufObject
189       else
190         Mask := CreateGdkMaskBitmap(BitmapHandle, MaskHandle);
191 
192       Img := gtk_image_new;
193 
194       if Pixbuf <> nil then
195         gtk_image_set_from_pixbuf(PGtkImage(Img), Pixbuf)
196       else
197         gtk_image_set_from_pixmap(PGtkImage(Img), GDIObject^.GDIPixmapObject.Image, Mask);
198       gtk_button_set_image(PGtkButton(NewButton), Img);
199       if Mask <> nil then
200         g_object_unref(Mask);
201       DeleteObject(BitmapHandle);
202       DeleteObject(MaskHandle);
203     end;
204   end;
205   *)
206 end;
207 
lcl_resultnull208 function TGtk3DialogFactory.lcl_result: integer;
209 begin
210   Result:=gtk_resp_to_lcl(DialogResult);
211 end;
212 
TGtk3DialogFactory.btn_resultnull213 function TGtk3DialogFactory.btn_result: integer;
214 begin
215   Result:=gtk_resp_to_btn(DialogResult);
216 end;
217 
TGtk3DialogFactory.MessageTypenull218 class function TGtk3DialogFactory.MessageType(ADialogType:longint):TGtkMessageType;
219 begin
220   case ADialogType of
221     idDialogWarning: Result := GTK_MESSAGE_WARNING;
222     idDialogError: Result := GTK_MESSAGE_ERROR;
223     idDialogInfo : Result := GTK_MESSAGE_INFO;
224     idDialogConfirm : Result := GTK_MESSAGE_QUESTION;
225   else
226     Result := GTK_MESSAGE_INFO;
227   end;
228 end;
229 
230 
231 const
232   ButtonResults : array[mrNone..mrYesToAll] of Longint = (
233     -1, idButtonOK, idButtonCancel, idButtonAbort, idButtonRetry,
234     idButtonIgnore, idButtonYes,idButtonNo, idButtonAll, idButtonNoToAll,
235     idButtonYesToAll);
236 
237 constructor TGtk3DialogFactory.CreateAsk(const DialogCaption,
238        DialogMessage: string; DialogType: LongInt;
239        Buttons: TDialogButtons; HelpCtx: Longint);
240 var
241   GtkDialogType: TGtkMessageType;
242   Btns: TGtkButtonsType;
243   i, BtnIdx, BtnID: Integer;
244   dbtn:TDialogButton;
245   Title: String;
246   BtnResult: LongInt;
247 begin
248   DialogResult := mrNone;
249   fDialogType := DialogType;
250   GtkDialogType := MessageType(fDialogType); // map LCLINTF -> GTK
251   fButtons:=Buttons;
252   fCaption:=DialogCaption;
253 
254   Btns := GTK_BUTTONS_NONE;
255   DefaultNdx := 0;
256   for i := 0 to Buttons.Count - 1 do
257   begin
258     if Buttons[i].Default then
259       DefaultNdx := i;
260 
261     if (DialogResult = mrNone) and
262       (Buttons[i].ModalResult in [mrCancel, mrAbort, mrIgnore, mrNo, mrNoToAll])
263     then
264       DialogResult := Buttons[i].ModalResult;
265   end;
266 
267   Dialog := gtk_message_dialog_new(nil, GTK_DIALOG_MODAL, GtkDialogType, Btns, nil , []);
268 
269   set_message_text(DialogMessage);
270 
271   g_signal_connect_data(Dialog, 'delete-event',
272     TGCallback(@BoxClosed),
273     @DialogResult, nil, 0);
274 
275   if Btns = GTK_BUTTONS_NONE then
276   begin
277     // gtk3 have reverted buttons eg. No, Yes
278     for BtnIdx := Buttons.Count - 1 downto 0 do
279     begin
280       dbtn:=Buttons[BtnIdx];
281       if (dbtn.ModalResult >= Low(ButtonResults)) and (dbtn.ModalResult <= High(ButtonResults)) then
282       begin
283         BtnID := ButtonResults[dbtn.ModalResult];
284         case BtnID of
285           idButtonOK       : CreateButton(dbtn.Caption, GTK_RESPONSE_OK, BtnID);
286           idButtonCancel   : CreateButton(dbtn.Caption, GTK_RESPONSE_CANCEL, BtnID);
287           idButtonHelp     : CreateButton(dbtn.Caption, GTK_RESPONSE_HELP, BtnID);
288           idButtonYes      : CreateButton(dbtn.Caption, GTK_RESPONSE_YES, BtnID);
289           idButtonNo       : CreateButton(dbtn.Caption, GTK_RESPONSE_NO, BtnID);
290           idButtonClose    : CreateButton(dbtn.Caption, GTK_RESPONSE_CLOSE, BtnID);
291           idButtonAbort    : CreateButton(dbtn.Caption, GTK_RESPONSE_REJECT, BtnID);
292           idButtonRetry    : CreateButton(dbtn.Caption, GTK_RESPONSE_LCL_RETRY, BtnID);
293           idButtonIgnore   : CreateButton(dbtn.Caption, GTK_RESPONSE_LCL_IGNORE, BtnID);
294           idButtonAll      : CreateButton(dbtn.Caption, GTK_RESPONSE_LCL_ALL, BtnID);
295           idButtonNoToAll  : CreateButton(dbtn.Caption, GTK_RESPONSE_LCL_NOTOALL, BtnID);
296           idButtonYesToAll : CreateButton(dbtn.Caption, GTK_RESPONSE_LCL_YESTOALL, BtnID);
297         end;
298       end else
299          CreateButton(dbtn.Caption, dbtn.ModalResult, 0);
300 
301     end;
302   end;
303 
304   update_widget_list(@btn_coll_info);
305 
306 end;
307 
308 
TGtk3DialogFactory.btn_coll_infonull309 function TGtk3DialogFactory.btn_coll_info(ndx:integer):longint;
310 begin
311   Result:=fButtons[ndx].ModalResult; // get modal result for button
312 end;
313 
btn_ptr_infonull314 function TGtk3DialogFactory.btn_ptr_info(ndx:integer):longint;
315 begin
316   Result:=pButtons[ndx];
317 end;
318 
319 procedure TGtk3DialogFactory.set_message_text(const msg: string;const is_pango_markup:boolean=false);
320 var
321   ma:PGtkWidget;
322   mainList,ChildList:PgList;
323 begin
324   if is_pango_markup then
325     gtk_message_dialog_set_markup(PGtkMessageDialog(Dialog), PGChar(msg))
326   else
327   begin
328     ma:=PGtkMessageDialog(Dialog)^.get_message_area();
329     MainList := gtk_container_get_children(PGtkContainer(ma));
330     if Assigned(MainList) then
331     begin
332       PGtkLabel(MainList^.data)^.set_label(PGChar(msg));
333       g_list_free(MainList);
334     end;
335 
336   end;
337 end;
338 
339 procedure TGtk3DialogFactory.update_widget_list(const func:TBtnListFunction);
340 var
341   btn:PgtkButton;
342   BtnIdx,BtnID,BtnRes:integer;
343   MainList,ChildList: PGList;
344 begin
345   MainList := gtk_container_get_children(PGtkContainer(Dialog^.get_action_area));
346   ChildList:=g_list_last(MainList);
347   BtnIdx:=0;
348   btn_def:=nil;
349   while Assigned(ChildList) do
350   begin
351     if (ChildList^.Data <> nil) then
352     begin
353       if g_type_check_instance_is_a(ChildList^.Data, gtk_button_get_type) then
354       begin
355         Btn := PGtkButton(ChildList^.Data);
356 
357         BtnRes:=func(BtnIdx); // process button
358 
359         if (BtnRes>=Low(ButtonResults)) and (BtnRes<=High(ButtonResults)) then
360           BtnID := ButtonResults[BtnRes]
361         else
362           BtnID := BtnRes;
363 
364         if BtnID = idButtonCancel then
365            g_object_set_data(PGObject(Dialog), 'modal_result', Pointer(idButtonCancel));
366 
367         g_signal_connect_data(Btn, 'clicked',
368           TGCallback(@ButtonClicked), @DialogResult, nil, 0);
369 
370         if DefaultNdx = BtnIdx then
371         begin
372           gtk_dialog_set_default_response(Dialog, ResponseID(BtnID));
373           btn_def:=btn;
374           gtk_widget_grab_default(btn);
375           gtk_widget_grab_focus(btn);
376           gtk_widget_set_can_default(btn_def,TRUE);
377           gtk_window_set_default(dialog, btn_def);
378           g_object_set_data(PGObject(Dialog), 'modal_result',
379             {%H-}Pointer(PtrInt(BtnID)));
380         end;
381 
382         inc(BtnIdx);
383       end;
384     end;
385     ChildList:=ChildList^.prev;
386   end;
387   if MainList <> nil then
388     g_list_free(MainList);
389 
390 end;
391 
392 procedure TGtk3DialogFactory.run;
393 var
394   Title:string;
395 begin
396   if not Assigned(Dialog) then exit;
397 
398   if fCaption <> '' then
399     Title:=fCaption
400   else
401   begin
402     Title := '';
403     case fDialogType of
404       idDialogWarning: Title := rsMtWarning;
405       idDialogError: Title := rsMtError;
406       idDialogInfo : Title := rsMtInformation;
407       idDialogConfirm : Title := rsMtConfirmation;
408     end;
409   end;
410 
411   gtk_window_set_title(PGtkWindow(Dialog), PGChar(Title));
412   gtk_dialog_run(Dialog);
413 end;
414 
TGtk3DialogFactory.trnull415 class function TGtk3DialogFactory.tr(UseWidgetStr: boolean; const TranslatedStr, WidgetStr: String): string;
416 begin
417   if UseWidgetStr then
418     Result:=WidgetStr
419   else
420     Result:=TranslatedStr;
421 end;
422 
423 destructor TGtk3DialogFactory.Destroy;
424 begin
425   if Assigned(Dialog) then
426   gtk_widget_destroy(Dialog);
427 end;
428 
429 
430 constructor TGtk3DialogFactory.CreatePrompt(const DialogCaption,
431   DialogMessage: string; DialogType: LongInt; Buttons: PLongInt;
432   ButtonCount: LongInt; DefaultIndex: LongInt; EscapeResult: LongInt);
433 var
434   x,i:integer;
435   GtkDialogType: TGtkMessageType;
436   Btns: TGtkButtonsType;
437   DefaultID: Integer;
438 begin
439   DialogResult := EscapeResult;
440   fDialogType := DialogType;
441   GtkDialogType := MessageType(fDialogType); // map LCLINTF -> GTK
442   pButtons:=Buttons;
443   fCaption:=DialogCaption;
444 
445   Btns := GTK_BUTTONS_NONE;
446   DefaultId := 0;
447   for X := 0 to ButtonCount - 1 do
448   begin
449     if X = DefaultIndex then
450       DefaultID := Buttons[X];
451   end;
452 
453   Dialog := gtk_message_dialog_new(nil, GTK_DIALOG_MODAL, GtkDialogType, Btns, nil , []);
454 
455   set_message_text(DialogMessage);
456 
457   g_signal_connect_data(GPointer(Dialog), 'delete-event',
458     TGCallback(@BoxClosed),
459     @DialogResult, nil, 0);
460 
461   if Btns = GTK_BUTTONS_NONE then
462   begin
463     for i := ButtonCount-1 downto 0 do
464     begin
465       case Buttons[i] of
466         idButtonOK       : CreateButton(tr(rsmbOK='&OK',rsmbOK, 'gtk-ok'), GTK_RESPONSE_OK);
467         idButtonCancel   : CreateButton(tr(rsmbCancel='Cancel',rsmbCancel,'gtk-cancel'), GTK_RESPONSE_CANCEL);
468         idButtonHelp     : CreateButton(tr(rsmbHelp='&Help',rsmbHelp,'gtk-help'), GTK_RESPONSE_HELP);
469         idButtonYes      : CreateButton(tr(rsmbYes='&Yes',rsmbYes,'gtk-yes'), GTK_RESPONSE_YES);
470         idButtonNo       : CreateButton(tr(rsmbNo='&No',rsmbNo,'gtk-no'), GTK_RESPONSE_NO);
471         idButtonClose    : CreateButton(tr(rsmbClose='&Close',rsmbClose,'gtk-close'), GTK_RESPONSE_CLOSE);
472         idButtonAbort    : CreateButton(rsMBAbort, GTK_RESPONSE_REJECT);
473         idButtonRetry    : CreateButton(rsMBRetry, GTK_RESPONSE_LCL_RETRY);
474         idButtonIgnore   : CreateButton(rsMBIgnore, GTK_RESPONSE_LCL_IGNORE);
475         idButtonAll      : CreateButton(rsMbAll, GTK_RESPONSE_LCL_ALL);
476         idButtonNoToAll  : CreateButton(rsMBNoToAll, GTK_RESPONSE_LCL_NOTOALL);
477         idButtonYesToAll : CreateButton(rsMBYesToAll, GTK_RESPONSE_LCL_YESTOALL);
478       end;
479     end;
480   end;
481   update_widget_list(@btn_ptr_info);
482 end;
483 
484 
485 constructor TGtk3DialogFactory.CreateMsgBox1(hWnd: HWND; lpText, lpCaption: PChar;
486   uType: Cardinal);
487 var
488   ALabel : PGtkWidget;
489   ButtonCount, DefButton : Integer;
490 (*  procedure CreateButton(const ALabel : PChar; const RetValue : integer);
491   var AButton : PGtkWidget;
492   begin
493     AButton:= gtk_button_new_with_label(ALabel);
494     Inc(ButtonCount);
495     if ButtonCount = DefButton then begin
496       gtk_window_set_focus(PGtkWindow(Dialog), AButton);
497     end;
498     { If there is the Cancel button, allow the dialog to close }
499     if RetValue = IDCANCEL then begin
500       g_object_set_data(PGObject(Dialog), 'modal_result', Pointer(IDCANCEL));
501     end;
502     g_object_set_data(AButton, 'modal_result',
503                         {%H-}Pointer(PtrInt(RetValue)));
504     g_signal_connect_data(AButton, 'clicked',
505                      TGCallback(@MessageButtonClicked), GPointer(@ADialogResult), nil, 0);
506     gtk_container_add (PGtkContainer(PGtkDialog(Dialog)^.get_action_area), AButton);
507   end;*)
508 
509 begin
510   ButtonCount:= 0;
511 
512   fCaption:=lpCaption;
513   { Determine which is the default button }
514   DefButton:= ((uType and $00000300) shr 8) + 1;
515   //DebugLn('Trace:Default button is ' + IntToStr(DefButton));
516 
517   DialogResult:= 0;
518   Dialog := gtk_dialog_new;
519   g_signal_connect_data(Dialog, 'delete-event', TGCallback(@BoxClosed), @DialogResult, nil, 0);
520   gtk_window_set_default_size(PGtkWindow(Dialog), 100, 100);
521   ALabel:= gtk_label_new(lpText);
522   gtk_container_add (PGtkContainer(PGtkDialog(Dialog)^.get_content_area), ALabel);
523   fDialogType:= (uType and $0000000F);
524   if fDialogType = MB_OKCANCEL
525   then begin
526     CreateButton(PChar(rsMbOK), IDOK);
527     CreateButton(PChar(rsMbCancel), IDCANCEL);
528   end
529   else begin
530     if fDialogType = MB_ABORTRETRYIGNORE
531     then begin
532       CreateButton(PChar(rsMbAbort), IDABORT);
533       CreateButton(PChar(rsMbRetry), IDRETRY);
534       CreateButton(PChar(rsMbIgnore), IDIGNORE);
535     end
536     else begin
537       if fDialogType = MB_YESNOCANCEL
538       then begin
539         CreateButton(PChar(rsMbYes), IDYES);
540         CreateButton(PChar(rsMbNo), IDNO);
541         CreateButton(PChar(rsMbCancel), IDCANCEL);
542       end
543       else begin
544         if fDialogType = MB_YESNO
545         then begin
546           CreateButton(PChar(rsMbYes), IDYES);
547           CreateButton(PChar(rsMbNo), IDNO);
548         end
549         else begin
550           if fDialogType = MB_RETRYCANCEL
551           then begin
552             CreateButton(PChar(rsMbRetry), IDRETRY);
553             CreateButton(PChar(rsMbCancel), IDCANCEL);
554           end
555           else begin
556             { We have no buttons to show. Create the default of OK button }
557             CreateButton(PChar(rsMbOK), IDOK);
558           end;
559         end;
560       end;
561     end;
562   end;
563   gtk_window_set_title(PGtkWindow(Dialog), lpCaption);
564   gtk_window_set_position(PGtkWindow(Dialog), GTK_WIN_POS_CENTER);
565   gtk_window_set_modal(PGtkWindow(Dialog), true);
566   gtk_widget_show_all(Dialog);
567 end;
568 
569 constructor TGtk3DialogFactory.CreateMsgBox(hWnd: HWND; lpText,
570   lpCaption: PChar; uType: Cardinal);
571 var
572   AType,AButtons,DefIndex:integer;
573   btns:array of integer;
574 
575   procedure AddBtn(btn_res:integer);
576   begin
577     setlength(btns,length(btns)+1);
578     btns[high(btns)]:=btn_res;
579   end;
580 
581 begin
582   // icons
583   case uType and $000000F0 of
584 //  MB_ICONEXCLAMATION:
585   MB_ICONWARNING: AType:=idDialogWarning;
586   //MB_ICONASTERISK:
587   MB_ICONINFORMATION: AType:=idDialogInfo;
588   MB_ICONQUESTION: Atype:=idDialogConfirm;
589   // MB_ICONSTOP:
590   // MB_ICONHAND:
591   MB_ICONERROR: Atype:=idDialogError;
592   end;
593   // default button
594   DefIndex:=(uType and $00000F00) shr 8;
595 
596   // buttons requested
597   AButtons:= (uType and $0000000F);
598   if AButtons = MB_OKCANCEL
599   then begin
600     AddBtn(idButtonOk);
601     AddBtn(idButtonCancel);
602   end
603   else begin
604     if AButtons = MB_ABORTRETRYIGNORE
605     then begin
606       AddBtn(idButtonAbort);
607       AddBtn(idButtonRetry);
608       AddBtn(idButtonIgnore);
609     end
610     else begin
611       if AButtons = MB_YESNOCANCEL
612       then begin
613         AddBtn(idButtonYes);
614         AddBtn(idButtonNo);
615         AddBtn(idButtonCancel);
616       end
617       else begin
618         if AButtons = MB_YESNO
619         then begin
620           AddBtn(idButtonYes);
621           AddBtn(idButtonNo);
622         end
623         else begin
624           if AButtons = MB_RETRYCANCEL
625           then begin
626             AddBtn(idButtonRetry);
627             AddBtn(idButtonCancel);
628           end
629           else begin
630             { We have no buttons to show. Create the default of OK button }
631             AddBtn(idButtonOK);
632           end;
633         end;
634       end;
635     end;
636   end;
637   Self.CreatePrompt(lpCaption,lpText,AType,@btns[0],length(btns),DefIndex,0);
638 end;
639 
640 
641 end.
642 
643