Thank you all, and you're all welcome
@srod: I first used WH_CALLWNDPROC but then I remembered using WH_CBT in one of my previous projects after reading somewhere (Google) that the WH_CBT uses less overhead since it reports back on fewer messages. The only messages we really need are the creation (HCBT_CREATEWND) and activation (HCBT_ACTIVATE) of our MessageRequester.
AND51 wrote:The checkbox overlaps the text and/or the buttons, if you have multi-line text!
I can't reproduce this. See if the new code works any better for you.
Use AskAgainRequester() in place of the native PB MessageRequester(). It takes the exact same parameters.
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
End