Help me to attach a file.hlp to MessageBox with the button "Help" (MB_HELP). Thank you in advance.
Maybe it's useless with MessageBox(), but with MessageBoxIndirect()#define WIN32_LEAN_AND_MEAN
#include <windows.h>
VOID CALLBACK MsgBoxCallback(LPHELPINFO lpHelpInfo)
{
//MessageBox(0,0,0,MB_OK);
WinHelp(0, "MyHelp.hlp", HELP_CONTEXT, lpHelpInfo->dwContextId);
}
void __cdecl WinMainCRTStartup(void)
{
MSGBOXPARAMS mbp;
//memset(&mbp, 0, sizeof(mbp));
mbp.cbSize = sizeof(mbp);
mbp.hwndOwner = 0;
mbp.hInstance = GetModuleHandle(NULL);
mbp.lpszText = "Text";
mbp.lpszCaption = "Caption";
mbp.dwStyle = MB_HELP;
mbp.lpszIcon = 0;
mbp.dwContextHelpId = 1; // help topic ID
mbp.lpfnMsgBoxCallback = MsgBoxCallback;
mbp.dwLanguageId = 0;
int rc = MessageBoxIndirect(&mbp);
ExitProcess(0);
}
Paljon kiitoksia, Timo!
Can just do the same with simple MessageBox? How do MsgBoxCallback? Via WM_HELP? Or track pressing the F1 key?
Use your main window's handle when calling the message box
invoke MessageBox,mainwnd,0,0,MB_OK or MB_HELP
In your main window's message loop for WM_HELP
invoke ShellExecute,0,0,offset hlpfile,0,0,1
Hi, sinsi!
Thank you very much!
In the meantime I found a place where you can download the Winhelp compiler and produce great retro old-fashioned help files even from Windows 10 64-bit (I tested :t). http://www.divcomsoft.com/info/helpcompilers.php
Hi, José!
Thank you very much!
José,
That page links to a Microsoft ftp server, and it doesn't work. But this one is OK - first link on top: http://www.rtfc.de/rtfc0031.html
Direct link: http://download.microsoft.com/download/word97win/Utility/4.03/WIN98/EN-US/Hcwsetup.exe
Ciao, jj2007! Come sta?
Sto bene, Mikl, e tu? Gli orsi nel tuo cortile si comportano bene? ;-)
I've made a little test with the WM_HELP message. It works but the message gets already fired when you show the MsgBox; therefore you must check for iCtrlId (demo attached):GuiParas equ "Help demo", x660, y50, w100, h100
include \masm32\MasmBasic\Res\MbGui.asm
Event Message
.if uMsg_==WM_HELP
mov ecx, lParam_
hi equ [ecx.HELPINFO]
deb 4, "Help", hi.iContextType, hi.iCtrlId, hi.hItemHandle, hi.dwContextId, hi.MousePos.x
.if hi.iCtrlId ; #### this check is essential! ####
PrintLine "Lauching help"
ShEx "\Masm32\help\hlhelp.chm"
.endif
.endif
Event Paint
GuiTextBox 9, 9, 99.0-18, 99.0-18, "Hit F1", bcol RgbCol(160, 255, 255)
Event Key
.if VKey==VK_F1
MsgBox hWnd_, "Click the ? to get macro help", "Hi", MB_OK or MB_HELP
.endif
GuiEnd
OPT_Susy Console ; force console build
@jj2007 if key F2 opens that MessageBox that WM_HELP handling works normally ?
Excellent point, Timo! In fact, F1 seems to trigger WM_HELP, F2 doesn't.
Hi Mikl__,
You can subclass the message box and control the help button.
include MBox.inc
.data
capt db "Hello!",0
msg db 'Customized message box',0
msg2 db 'You clicked the Help button',0
ButtonText db 'Click here',0
bclass db 'Button',0
.data?
pOldProc dd ?
HelpBtnID dd ?
.code
start:
invoke CustMsgBox,0,ADDR msg,ADDR capt,ADDR ButtonText
invoke ExitProcess,0
CustMsgBox PROC uses esi handle:DWORD,message:DWORD,caption:DWORD,button:DWORD
LOCAL ThreadID:DWORD
LOCAL hWnd:DWORD
LOCAL hThread:DWORD
LOCAL hClick:DWORD
invoke CreateThread,0,0,ADDR ThreadProc,\
ADDR caption,0,ADDR ThreadID
mov hThread,eax
invoke GetCurrentProcess
invoke WaitForInputIdle,eax,INFINITE
invoke EnumWindows,ADDR EnumWndProc,\
ADDR ThreadID
invoke FindWindowEx,hWnd,0,ADDR bclass,0
mov hClick,eax
invoke FindWindowEx,hWnd,eax,ADDR bclass,0
invoke GetDlgCtrlID,eax
mov HelpBtnID,eax
invoke SetWindowText,hClick,button
invoke SetWindowLong,hWnd,GWL_WNDPROC,\
ADDR MsgboxProc
mov pOldProc,eax
invoke WaitForSingleObject,hThread,INFINITE
invoke CloseHandle,hThread
ret
CustMsgBox ENDP
ThreadProc PROC pParams:DWORD
mov eax,pParams
invoke MessageBox,DWORD PTR [eax-8],\
DWORD PTR [eax-4],DWORD PTR [eax],\
MB_HELP
ret
ThreadProc ENDP
EnumWndProc PROC hWnd:DWORD,lParam:DWORD
LOCAL pid:DWORD
invoke GetWindowThreadProcessId,hWnd,ADDR pid
mov edx,lParam
cmp eax,[edx]
jne @f
push hWnd
pop DWORD PTR [edx-4] ; get the handle of the window
xor eax,eax ; displaying the message box
ret
@@:
mov eax,TRUE
ret
EnumWndProc ENDP
MsgboxProc PROC hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
.IF uMsg == WM_COMMAND
mov eax,wParam
mov edx,eax
shr edx,16
.IF dx==BN_CLICKED
mov ecx,HelpBtnID
.IF ax==cx
invoke MessageBox,0,ADDR msg2,ADDR capt,MB_OK
.ENDIF
.ENDIF
.ENDIF
invoke CallWindowProc,pOldProc,hWnd,uMsg,wParam,lParam
ret
MsgboxProc ENDP
END start
Very cute technique, Erol :t
Buona sera, jj2007! I cuccioli di orso sono cresciuti molto e sono diventati pericolosi, quindi ho dovuto darli allo zoo.
Hi, Erol! Thank you very much for excellent example!
Many thanks to everyone who helped me in writing this program! (https://wasm.in/styles/smiles_s/drinks.gif)
; GUI #
include win64a.inc
HELPINFO struct
cbSize dq ?
iContextType dq ?
iCtrlId dq ?
hItemHandle dq ?
dwContextId dq ?
MousePos POINT <>
HELPINFO ends
.code
WinMain proc
local msg:MSG
xor ebx,ebx
mov esi,IMAGE_BASE
mov edi,offset ClassName
mov ecx,offset FileName
invoke LoadCursorFromFile
push rax ;hIconSm
push rdi ;lpszClassName
push rbx ;lpszMenuName
push COLOR_WINDOW+1;hbrBackground
push 10003h ;hCursor
push rax ;hIcon
push rsi ;hInstance
push rbx ;cbClsExtra & cbWndExtra
pushaddr WndProc ;lpfnWndProc
push sizeof WNDCLASSEX;cbSize & style
invoke RegisterClassEx,esp ;addr WNDCLASSEX
push rbx
push rsi ;rsi=400000h
shl esi,9 ;rsi=CW_USEDEFAULT
push rbx
push rbx
push rsi
push rsi
push rsi
push rsi
sub esp,20h
mov r9d,WS_OVERLAPPEDWINDOW or WS_VISIBLE
invoke CreateWindowEx,0,edi,edi
mov hwnd,rax
lea edi,msg
@@: invoke GetMessage,edi,NULL,0,0
invoke TranslateMessage,edi
invoke DispatchMessage,edi
jmp @b
WinMain endp
WndProc proc hWnd:QWORD,uMsg:QWORD,wParam:QWORD,lParam:QWORD
local ps:PAINTSTRUCT
local expRect:RECT
mov hWnd,rcx
mov wParam,r8
mov lParam,r9
cmp edx,WM_DESTROY
je wmDESTROY
cmp edx,WM_PAINT
je wmPAINT
cmp edx,WM_HELP
je wmHELP
cmp edx,WM_KEYDOWN
je wmF1
leave
jmp NtdllDefWindowProc_
wmDESTROY: invoke RtlExitUserProcess,NULL
wmPAINT:invoke BeginPaint,,addr ps
invoke GetClientRect,hWnd,addr expRect
mov edx,offset message
invoke DrawText,ps.hdc,,-1,addr expRect,DT_SINGLELINE or DT_CENTER or DT_VCENTER
invoke EndPaint,hWnd,addr ps
jmp wmBYE
wmHELP: mov rax,[r9+HELPINFO.iCtrlId]
cmp rax,hwnd
je wmBYE
mov r8d,offset hlpfile
invoke ShellExecute,0,0,,0,0,1
jmp wmBYE
wmF1: cmp r8,VK_F1
jne wmBYE
mov edx,offset message2
mov r8d,offset ClassName
invoke MessageBox,hwnd,,,MB_HELP
wmBYE: leave
ret
WndProc endp
.data
ClassName db "Uncle Remus tales:#3 Simple window",0
FileName db "..\Images\br_Rabbit3.cur",0
message db "Press on F1 button",0
message2 db 'Press on "Help"',0
hlpfile db 'tut_01.hlp',0
hwnd dq ?
end
I have done an example in C/C++ including an WinHelp file with help context 10 which will be requested in the example. It will be elementary to convert to asm but I will not do it because am very lazy these days.
#include "windows.h"
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
WNDCLASS windowClass = { 0 };
windowClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hInstance = NULL;
windowClass.lpfnWndProc = WndProc;
windowClass.lpszClassName = L"Window in Console Application";
windowClass.style = CS_HREDRAW | CS_VREDRAW;
if (!RegisterClass(&windowClass))
MessageBox(NULL, L"Error registering class", L"Error", MB_OK);
HWND windowHandle = CreateWindow(L"Window in Console Application",
NULL,
WS_POPUP,
0,
0,
GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN),
NULL,
NULL,
NULL,
NULL);
MessageBox(windowHandle, L"Help me", L"Hello HELP", MB_HELP);
MSG messages;
while (GetMessage(&messages, NULL, 0, 0) > 0)
{
TranslateMessage(&messages);
DispatchMessage(&messages);
}
return messages.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
{
switch (message)
{
case WM_HELP:
WinHelp(0, L"MyHelp.hlp", HELP_CONTEXT, 10);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wparam, lparam);
}
return 0;
}
here it's a version from the c one. It's a console application. Unfortunately, like all the others old .hlp files i can only see the content with the help of a program that i donwloaded from this forum (don't remember where). This program just open the helpless windows 8.1 help which dosn't help me at all... :icon_exclaim:
In this thread (https://answers.microsoft.com/en-us/windows/forum/windows_10-other_settings/winhlp32exe-windows-10/5971eda3-3a07-4156-af2a-926c65eb5a0c) there is a link to a google drive where there is winhlp32-windows-7-10-x86-64.zip
Help files downloaded from the internet will need to be unblocked - right click/properties/Unblock or whatever equivalent they invented.
This one that Jim posted a while ago works fine.
http://masm32.com/board/index.php?topic=5201.0
I think that's the one i use (jim's version). It works pretty well. :t
Hi, All!
Why do I click on the "Help" button, but the call for help does not occur?
asm-file; GUI #
include win64a.inc
MSGBOXDATA struct
params MSGBOXPARAMS <>
pwndOwner QWORD ?
wLanguageId DWORD ?,?
pidButton QWORD ? ; // Array of button IDs
ppszButtonText QWORD ? ; // Array of button text strings
cButtons DWORD ?
DefButton DWORD ?
CancelId DWORD ?
Timeout DWORD ?
MSGBOXDATA ends
.code
hlpfile db 'Uncle Remus Tales.chm',0
MsgBoxText1: du <Win64 Assembly is Great>
MsgCaption8: du <SoftModalMessageBox>
sBTN1: du <OK>
sBTN2: du <Help>
dwBtnIds dd 1,0
dwTxtTbl dq sBTN1,sBTN2
align 16
WinMain proc
local mb:MSGBOXPARAMS
local mbxData:MSGBOXDATA
mov mbxData.params.cbSize,sizeof MSGBOXPARAMS
and mbxData.params.hwndOwner,0
mov mbxData.params.hInstance,IMAGE_BASE
movr mbxData.params.lpszText,MsgBoxText1 ;text address
movr mbxData.params.lpszCaption,MsgCaption8 ;title address
mov mbxData.params.dwStyle,MB_USERICON or MB_HELP
movr mbxData.params.lpszIcon,1000
mov mbxData.params.dwContextHelpId,1
movr mbxData.params.lpfnMsgBoxCallback,MsgBoxCallback
and mbxData.params.dwLanguageId,0
and mbxData.pwndOwner,0
and mbxData.wLanguageId,0
movr mbxData.pidButton,dwBtnIds
movr mbxData.ppszButtonText,dwTxtTbl
mov mbxData.cButtons,2
and mbxData.DefButton,0
mov mbxData.CancelId,1
or mbxData.Timeout,-1
lea ecx,mbxData
invoke SoftModalMessageBox
invoke RtlExitUserProcess,NULL
WinMain endp
align 16
MsgBoxCallback proc lpHelpInfo:qword;(LPHELPINFO lpHelpInfo)
mov r8d,offset hlpfile
invoke ShellExecute,0,0,,0,0,1
leave
retn
MsgBoxCallback endp
end
rc-file1000 ICON DISCARDABLE "br_Bear4.ico"
I dealt with the problemdwBtnIds dd IDOK,IDHELP
mov r8d,offset hlpfile ?
Ah, you build with /LARGEADDRESSAWARE:NO :(