@AND51: You can pick and choose which MessageRequesters to hook. You just call the SetWindowsHookEx() as needed prior to using MessageRequester().
I'll clean this up and make it more user friendly later this weekend.
Code: Select all
onErrorGoto(?Fred)Code: Select all
onErrorGoto(?Fred)I can't reproduce this. See if the new code works any better for you.AND51 wrote:The checkbox overlaps the text and/or the buttons, if you have multi-line text!
Code: Select all
; *****************************************************
; Code : MessageRequester with "Don't ask me again"
; Author : Sparkie
; Date : November 18, 2006
; OS : Windows only
; License : It's all yours to use as you so desire
; (props/credit would be nice)
; *****************************************************
Global hHook.l = 0, oldProc.l = 0, askagain.l = 0
;...These are missing in PB def
#BS_TEXT = 0
#IDABORT = 3
#IDTRYAGAIN = 10
#IDCONTINUE = 11
;...Make sure Checkbox ID <> any of the other MessageRequester buttons
#CheckBoxID = 12
;...Subclassed MessageRequester Procedure()
Procedure MsgBoxProc(hwnd.l, msg.l, wParam.l, lParam.l)
result.l = CallWindowProc_(oldProc, hwnd, msg, wParam, lParam)
Select msg
Case #WM_DESTROY
;...Get handle to our checkbox
hCheckBox.l = GetDlgItem_(hwnd, #CheckBoxID)
;...Get the checkbox state. <0 = not checked> <1 = checked>
;...For this test I'll set a Global var to = CheckBox state
;...In a real app you could set the value in a config/ini file
;...or maybe a use a Registry setting
askagain = SendMessage_(hCheckBox, #BM_GETCHECK, 0, 0)
EndSelect
ProcedureReturn result
EndProcedure
;...Our hook Procedure()
Procedure CBTProc(nCode.l, wParam.l, lParam.l)
result.l = CallNextHookEx_(hHook, nCode,wParam,lParam)
;...Creation of MessageRequester is here
If nCode = #HCBT_CREATEWND
*cbt_cw.CBT_CREATEWND = lParam
*lpcs.CREATESTRUCT = *cbt_cw\lpcs
;...Take action only if this is our MessageRequester
If *lpcs\hWndParent = WindowID(0) And *lpcs\lpszClass = 32770
;...Resize the MessageRequester to make room for our CheckBoxGadget
*lpcs\cy + 25
EndIf
result = 0
EndIf
;...MessageRequester is about to become active
;...Here we will add our "Don't ask me this again" checkbox
If nCode = #HCBT_ACTIVATE
hMsgBox.l = wParam
;...Subclass the MessageRequester
oldProc = SetWindowLong_(hMsgBox, #GWL_WNDPROC, @MsgBoxProc())
hFont.l = GetStockObject_(#DEFAULT_GUI_FONT)
StartDrawing(WindowOutput(0))
DrawingFont(hFont)
cbWidth = TextWidth("Don't ask me this again.") + 22 ; add room for checkbox
cbHeight = TextHeight("Don't ask me this again.")
StopDrawing()
;...Determine Checkbox placement
GetWindowRect_(hMsgBox, @winRC.RECT)
pt.POINT\x = winRC\left
pt.POINT\y = winRC\bottom
ScreenToClient_(hMsgBox, pt)
cbX = 10
cbY = (pt\y - cbHeight) - 10
hCheckBox.l = CreateWindowEx_(0, "Button", "Don't ask me this again.", #BS_AUTOCHECKBOX | #BS_TEXT | #WS_GROUP | #WS_TABSTOP | #WS_CHILD | #WS_VISIBLE, cbX, cbY, cbWidth, cbHeight, hMsgBox, #CheckBoxID, GetModuleHandle_(0), 0)
SendMessage_(hCheckBox, #WM_SETFONT, hFont, 0)
;...Release the hook
UnhookWindowsHookEx_(hHook)
hHook = 0
result = 0
EndIf
ProcedureReturn result
EndProcedure
;...Procedure for custom MessageRequester with "Don't ask again" CheckBox
Procedure AskAgainRequester(caption$, message$, buttons_icon)
hHook = SetWindowsHookEx_(#WH_CBT, @CBTProc(), 0, GetCurrentThreadId_())
If hHook
result = MessageRequester(caption$, message$, buttons_icon)
EndIf
ProcedureReturn result
EndProcedure
;Procedure to diplay the result from MessageRequester
Procedure.s DisplayAnswer(ans.l)
Select ans
Case #IDABORT
ans$ = "Abort"
Case #IDCANCEL
ans$ = "Cancel"
Case #IDCONTINUE
ans$ = "Continue"
Case #IDIGNORE
ans$ = "Ignore"
Case #IDNO
ans$ = "No"
Case #IDOK
ans$ = "Ok"
Case #IDRETRY
ans$ = "Retry"
Case #IDTRYAGAIN
ans$ = "Try Again"
Case #IDYES
ans$ = "Yes"
EndSelect
ProcedureReturn ans$
EndProcedure
If OpenWindow(0, 100, 100, 300, 200, "Don't ask me again", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
ButtonGadget(1, 10, 40, 280, 25, "Display Custom MessageRequester")
ButtonGadget(2, 10, 80, 280, 25, "Display Normal MessageRequester")
TextGadget(3, 10, 120, 280, 50, "")
Repeat
Event.l = WaitWindowEvent()
If Event = #PB_Event_Gadget
Select EventGadget()
Case 1
SetGadgetText(3, "")
ans$ = ""
answer.l = AskAgainRequester("Welcome", "Do you want to continue?", #MB_YESNOCANCEL | #MB_ICONQUESTION)
If askagain
ans$ + #CRLF$ + "Don't ask me again was checked"
Else
ans$ + #CRLF$ + "Don't ask me again was not checked"
EndIf
SetGadgetText(3, "The answer was " + DisplayAnswer(answer) + #CRLF$ + ans$)
Case 2
SetGadgetText(3, "")
answer.l = MessageRequester("Hello", "No hook is being used right now.", #MB_OK | #MB_ICONINFORMATION)
SetGadgetText(3, "The answer was " + DisplayAnswer(answer))
EndSelect
EndIf
Until Event = #PB_Event_CloseWindow
EndIf
;...Just in case it's still there
If hHook
UnhookWindowsHookEx_(hHook)
hHook = 0
EndIf
EndCode: Select all
; *******************************************************************************
; Code : MessageRequester with "In the future, do not show me this dialog box"
; Author : Sparkie
; Date : November 18, 2006
; OS : Windows only
; Notes : Use at your own risk as this reads/writes in the Registry
; License : It's all yours to use as you so desire
; (props/credit would be nice)
; *******************************************************************************
If OSVersion() > #PB_OS_Windows_ME
If OpenWindow(0, 100, 100, 300, 200, "Don't ask me again", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
ButtonGadget(1, 10, 40, 280, 25, "Display Custom MessageRequester")
ButtonGadget(2, 10, 70, 280, 25, "Delete Registry Entry to enable MessageRequester")
DisableGadget(2, 1)
Repeat
Event.l = WaitWindowEvent()
If Event = #PB_Event_Gadget
Select EventGadget()
Case 1
hdll = OpenLibrary(0, "shlwapi.dll")
If hdll
;...SHMessageBoxCheck() can only be called by it's ordinal
*shmbc = GetFunctionEntry(0, 185)
If *shmbc
;...6th parameter is value to return if this MessageRequester has been turned off
;...7th parameter is unique Registry identifier
result = CallFunctionFast(*shmbc, WindowID(0), @"This is a test of the SHMessageBoxCheck() Function", @"Welcome", #MB_YESNO, -1, @"SparkieSaysDeleteMe")
Select result
Case -1
;...MessageRequester has been disabled
;...Allow removal of Registry entry to re-enable Messagerequester
DisableGadget(2, 0)
Default
;...MessageRequester is still enabled
;...No need to delete Registry entry
DisableGadget(2, 1)
EndSelect
EndIf
CloseLibrary(0)
EndIf
Case 2
;...Delete Registry entry
hKey = 0
RegOpenKeyEx_(#HKEY_CURRENT_USER, @"Software\Microsoft\Windows\CurrentVersion\Explorer\DontShowMeThisDialogAgain", 0, #KEY_ALL_ACCESS, @hKey)
If hKey <> 0 And result = -1
RegDeleteValue_(hKey, @"SparkieSaysDeleteMe")
RegCloseKey_(hKey)
hKey = 0
DisableGadget(2, 1)
EndIf
EndSelect
EndIf
Until Event = #PB_Event_CloseWindow
EndIf
Else
MessageRequester("Sorry", "This requires a minimum of Win2K", #MB_OK | #MB_ICONEXCLAMATION)
EndIf
EndHi! I tried this message-text with your old code and th checkbox overlapped the text and the buttons.Great Sparkie wrote:I can't reproduce this. See if the new code works any better for you.AND51 wrote:The checkbox overlaps the text and/or the buttons, if you have multi-line text!
Code: Select all
AskAgainRequester("Welcome", "Do you want to continue?"+#CRLF$+#CRLF$+#CRLF$+#CRLF$+#CRLF$+#CRLF$+#CRLF$+#CRLF$+"There are many line-breaks... =(", #MB_YESNOCANCEL | #MB_ICONQUESTION) Code: Select all
onErrorGoto(?Fred)I'm not sure, but can't you import functions since PB 4.00 with Import and/or Prototype?Sparkie wrote:Here is another MessaageBox with a checkbox option. It's only for Win2K and up, and IMHO, it's not as useful as the previous example, but here it is just the same.
http://msdn.microsoft.com/library/defau ... xcheck.asp
Code: Select all
onErrorGoto(?Fred)A couple of variables need to be integers for it to work with C backend compiler... there could be more.BarryG wrote: Sun Apr 16, 2023 1:38 am Sparkie's code here doesn't work anymore (illegal memory access) -> viewtopic.php?p=171031#p171031
Anyone know how to fix it? Thanks.
Code: Select all
Global hHook.i = 0, oldProc.i = 0, askagain.l = 0