PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » PureBasic для Windows » MessageRequester с флажком "Больше не спрашивать"


MessageRequester с флажком "Больше не спрашивать"

Сообщений 1 страница 3 из 3

1

Написал код (возможно кроссплатформенный) используя свой старый 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)

0

2

ты второй код запускал?
строка 72
CreateGadgetList(WindowID(0))
и само окошко криво нарисовано, чек всю малину портит

а первый код нормально

0

3

newJS
У тебя портит, у меня нет, я ведь под свой шрифт рассчитывал, о чём я сообщил, что изменил 95 на 73. На счёт CreateGadgetList() обратись к Фреду, он ведь вчера его редактировал, спроси зачем он его воткнул (ссылка на оригинал во второй строке). То что этот код может криво отображаться я и сам знаю, поэтому и выложил два варианта. Тут просто второй он как бы основан на родном сообщении, и кому то он будет стабильней, хотя я не уверен. Ну и за счёт WinAPI у него нет кроссплатформенности.

0


Вы здесь » PureBasic - форум » PureBasic для Windows » MessageRequester с флажком "Больше не спрашивать"