Написал код (возможно кроссплатформенный) используя свой старый AutoIt3-код, даже не ожидал что тот же подход - новый цикл опроса сработает и в PureBasic
EnableExplicit Enumeration #Win0 #Win1 EndEnumeration Enumeration #w0_btn #w1_btnYes #w1_btnNo #w1_ch #w1_txt #StatusBar EndEnumeration Global LngCheck$, LngYes$, LngNo$, Title$, Text$, OSLang Define Answer Declare MsgAsk(Title$, Text$, Width = 270, Height = 170, ChBox = 0, LngCheck$ = "Not to ask any more", LngYes$ = "Yes", LngNo$ = "No", WinID = -1) Define UserIntLang, *Lang If OpenLibrary(0, "kernel32.dll") *Lang = GetFunction(0, "GetUserDefaultUILanguage") If *Lang UserIntLang = CallFunctionFast(*Lang) EndIf CloseLibrary(0) EndIf ; En LngCheck$ = "Not to ask any more" LngYes$ = "Yes" LngNo$ = "No" Title$ = "Message" Text$ = "Use as default?" ; Ru If UserIntLang = 1049 LngCheck$ = "Больше не спрашивать" LngYes$ = "OK" LngNo$ = "Отмена" Title$ = "Сообщение" Text$ = "Использовать по умолчанию?" EndIf OpenWindow(#Win0, 0, 0, 420, 300, "Win", #PB_Window_TitleBar | #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget) ButtonGadget(#w0_btn, 20, 20, 90, 30, "Question") TextGadget(#StatusBar, 20, 60, 330, 150 , "") Repeat Select WaitWindowEvent() Case #PB_Event_Gadget Select EventGadget() Case #w0_btn Answer = MsgAsk(Title$, Text$, 250, 100, 1, LngCheck$, LngYes$, LngNo$, #Win0) SetGadgetText(#StatusBar, "Answer = " + Str(Answer & 1) + #CRLF$ + "Check = " + Str(Answer & 2) + #CRLF$ + "Close = " + Str(Answer & 4)) EndSelect Case #PB_Event_CloseWindow CloseWindow(#Win0) End EndSelect ForEver Procedure MsgAsk(Title$, Text$, Width = 270, Height = 170, ChBox = 0, LngCheck$ = "Not to ask any more", LngYes$ = "Yes", LngNo$ = "No", WinID = -1) Protected Answer, hWnd If Width < 170 Width = 170 EndIf If WinID > -1 hWnd = WindowID(WinID) DisableWindow(WinID, 1) Else hWnd = 0 EndIf OpenWindow(#Win1, 0, 0, Width, Height, Title$, #PB_Window_SystemMenu | #PB_Window_ScreenCentered, hWnd) TextGadget(#w1_txt, 10, 10, Width - 20, Height - 75, Text$) CheckBoxGadget(#w1_ch, 10, Height - 65, Width - 20, 17, LngCheck$) ; SetGadgetState(#w1_ch, ChBox) If ChBox SetGadgetState(#w1_ch, #PB_Checkbox_Checked) EndIf ButtonGadget(#w1_btnYes, (Width - 150) / 2, Height - 40, 70, 28, LngYes$) ButtonGadget(#w1_btnNo, (Width - 150) / 2 + 80, Height - 40, 70, 28, LngNo$) Repeat Select WaitWindowEvent() Case #PB_Event_Gadget Select EventGadget() Case #w1_btnYes Answer | 1 Break Case #w1_btnNo Break EndSelect Case #PB_Event_CloseWindow Answer | 4 Break EndSelect ForEver If GetGadgetState(#w1_ch) Answer | 2 EndIf If hWnd DisableWindow(WinID, 0) EndIf CloseWindow(#Win1) ProcedureReturn Answer EndProcedure
ну и сразу подняли тему такой же мессаги на WinAPI, я его перевёл на русский язык и сделал две правки - уменьшил позицию чекбокса с 95 на 73, так как наваливался на кнопки и закомментировал *lpcs\cy + 30 так как увеличение высоты мессаги у меня на Win10 не сдвигает кнопки вниз, поэтому нет смысла в этом действии.
; Sparkie, updated for PB6+ by Fred ; https://www.purebasic.fr/english/viewtopic.php?p=171031#p171031 ; ***************************************************** ; Code : MessageRequester с флажком "Больше не спрашивать" ; Author : Sparkie ; Date : Ноябрь 17, 2006 ; OS : Windows только ; License : Вы можете использовать это по своему усмотрению. ; (упоминание авторства и ссылки на оригинал приветствуются) ; ***************************************************** Global hHook = 0, oldProc = 0, NotAskAgain = 0 ; Этого до сих пор нет в PB по умолчанию #BS_TEXT = 0 ; Убедитесь, что идентификатор флажка <> любой из других кнопок MessageRequester #CheckBoxID = 12 ; Подкласс процедуры MessageRequester() Procedure MsgBoxProc(hwnd, msg, wParam, lParam) result = CallWindowProc_(oldProc, hwnd, msg, wParam, lParam) Select msg Case #WM_DESTROY ; Получает дескриптор флажка hCheckBox = GetDlgItem_(hwnd, #CheckBoxID) ; Получает состояние флажка. 0 - не отмечено, 1 - отмечено ; Для этого теста добавлено: Global var = состояние CheckBox. ; В реальной программе можно сохранить значение в файл config/ini ; или, можно использовать настройку в реестре NotAskAgain = SendMessage_(hCheckBox, #BM_GETCHECK, 0, 0) EndSelect ProcedureReturn result EndProcedure ; наша hook Procedure() Procedure CBTProc(nCode, wParam, lParam) result = CallNextHookEx_(hHook, nCode, wParam, lParam) ; Здесь создание MessageRequester If nCode = #HCBT_CREATEWND *cbt_cw.CBT_CREATEWND = lParam *lpcs.CREATESTRUCT = *cbt_cw\lpcs ; Применить только если это наш MessageRequester If *lpcs\hWndParent = WindowID(0) And *lpcs\lpszClass = 32770 ; Измените размер MessageRequester, чтобы освободить место для нашего CheckBoxGadget. ; *lpcs\cy + 30 ; на Win10 не смещает вниз кнопки ОК, Отмена, так что это бессмысленно EndIf result = 0 EndIf ; MessageRequester вот-вот станет активным ; Здесь добавляется флажок "Больше не спрашивать". If nCode = #HCBT_ACTIVATE hMsgBox = wParam ; Подкласс MessageRequester oldProc = SetWindowLong_(hMsgBox, #GWL_WNDPROC, @MsgBoxProc()) hCheckBox = CreateWindowEx_(0, "Button", "Больше не спрашивать", #BS_AUTOCHECKBOX | #BS_TEXT | #WS_GROUP | #WS_TABSTOP | #WS_CHILD | #WS_VISIBLE, 10, 73, 150, 25, hMsgBox, #CheckBoxID, GetModuleHandle_(0), 0) hFont = GetStockObject_(#DEFAULT_GUI_FONT) SendMessage_(hCheckBox, #WM_SETFONT, hFont, 0) ; иначе жирный шрифт ; Освобождает hook If hHook UnhookWindowsHookEx_(hHook) hHook = 0 EndIf result = 0 EndIf ProcedureReturn result EndProcedure If OpenWindow(0, 100, 100, 300, 200, "Больше не спрашивать", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0)) ButtonGadget(1, 10, 40, 280, 27, "Показать свой MessageRequester") TextGadget(2, 10, 80, 280, 25, "") Repeat Event = WaitWindowEvent() If Event = #PB_Event_Gadget And EventGadget() = 1 ; Создаёт локальный хук для наблюдения за MessageRequester If NotAskAgain MessageRequester("Извини", "Вы просили больше не показывать это сообщение.", #MB_OK | #MB_ICONINFORMATION) Else hHook = SetWindowsHookEx_(#WH_CBT, @CBTProc(), 0, GetCurrentThreadId_()) MessageRequester("Добро пожаловать", "Вы хотите продолжить?", #MB_YESNO | #MB_ICONQUESTION) EndIf Select NotAskAgain Case 0 SetGadgetText(2, "Не отмечено 'Больше не спрашивать'") Case 1 SetGadgetText(2, "Отмечено 'Больше не спрашивать'") EndSelect EndIf Until Event = #PB_Event_CloseWindow EndIf ; На всякий случай повтороное удаление хука, если он все еще существует. If hHook UnhookWindowsHookEx_(hHook) hHook = 0 EndIf End
Отредактировано AZJIO (17.04.2023 09:50:01)