Click to See Complete Forum and Search --> : How to use a custom icon in a message box?


mapna
November 28th, 2006, 04:49 AM
Hi,

how can i use a custom icon in a message box? Seems that there's a system enumeration MB_USERICON that i could just use instead of using MB_ICONWARNING etc. system icons. But how can i get it to use my own .ico file?

Seems like MessageBoxIndirect has some features i might need in this one. Should i use it instead of the MessageBox function?

I'm getting a bit confused about this, i've found some VB examples doing this but none helping with C++.. Any help will be greatly appreciated!

Thanks,

Ilkka

zerver
November 28th, 2006, 05:33 AM
This is one way of doing it:

LRESULT CALLBACK MsgBoxHookProcTest(int nCode, WPARAM wParam, LPARAM lParam) {
char szClassName[100] = { NULL };
HWND hWndParent = NULL;

if((hWndParent = GetParent(((LPCWPRETSTRUCT)lParam)->hwnd)) == NULL)
hWndParent = GetDesktopWindow();

if(!(nCode < 0)) {
GetClassName(((LPCWPRETSTRUCT)lParam)->hwnd, szClassName, 100);

if(!lstrcmpi(szClassName, "#32770")) {

switch(((LPCWPRETSTRUCT)lParam)->message) {
case WM_INITDIALOG:
// SendMessage(GetDlgItem(((LPCWPRETSTRUCT)lParam)->hwnd, IDYES), WM_SETTEXT, 0, (LPARAM)"Test 1");
// SendMessage(GetDlgItem(((LPCWPRETSTRUCT)lParam)->hwnd, IDNO), WM_SETTEXT, 0, (LPARAM)"Test 2");
SendMessage(GetDlgItem(((LPCWPRETSTRUCT)lParam)->hwnd, 0x14), STM_SETICON,
(WPARAM)LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON)), 0);
break;
}
}
}

return CallNextHookEx((HHOOK)GetProp(hWndParent, "MsgBoxHook"), nCode, wParam, lParam);
}

int MessageBoxTest(HWND hWnd, LPCTSTR lpszText, LPCTSTR lpszCaption, UINT uType) {
MSGBOXPARAMS mbp = { NULL };
int nRet;

mbp.cbSize = sizeof(mbp);
mbp.hwndOwner = hWnd;
mbp.lpszText = lpszText;
mbp.lpszCaption = lpszCaption;
mbp.dwStyle = uType;

if(hWnd == NULL)
hWnd = GetDesktopWindow();

SetProp(hWnd, "MsgBoxHook", SetWindowsHookEx(WH_CALLWNDPROCRET, MsgBoxHookProcTest, NULL, GetCurrentThreadId()));

nRet = MessageBox(hWnd, lpszText, lpszCaption, uType);

if(GetProp(hWnd, "MsgBoxHook"))
UnhookWindowsHookEx((HHOOK)RemoveProp(hWnd, "MsgBoxHook"));

return nRet;
}

ovidiucucu
November 28th, 2006, 05:51 AM
[ Redirected thread ]

kkez
November 28th, 2006, 06:39 AM
zerver, why do you fill the MSGBOXPARAMS structure and then call MessageBox without it?
The use of the MSGBOXPARAMS structure with MessageBoxIndirect is correct, but i don't see the point in using a hook when you can specify the icon directly in the MSGBOXPARAMS structure!

MSGBOXPARAMS msgbox = {0};
msgbox.cbSize = sizeof(MSGBOXPARAMS);
msgbox.hwndOwner = NULL;
msgbox.hInstance = GetModuleHandle(NULL);
msgbox.lpszText = "Hello";
msgbox.lpszCaption = "World!";
msgbox.dwStyle = MB_OK | MB_SETFOREGROUND | MB_USERICON;
msgbox.lpszIcon = MAKEINTRESOURCE(IDI_ANICON);

MessageBoxIndirect(&msgbox);

zerver
November 28th, 2006, 06:53 AM
Sorry, the messageboxparams thing is simply something that I have forgotten to delete.

The hook was originally made to change the text of the messagebox buttons.

ovidiucucu
November 28th, 2006, 06:59 AM
Completing the solution given by kkez here is a function you can write:
int CustomMessageBox(HWND hWnd,
LPCTSTR lpText,
LPCTSTR lpCaption,
UINT uType,
UINT uIconResID)
{
MSGBOXPARAMS mbp;
mbp.cbSize = sizeof(MSGBOXPARAMS);
mbp.hwndOwner = hWnd;
mbp.hInstance = GetModuleHandle(NULL);
mbp.lpszText = lpText;
mbp.lpszCaption = lpCaption;
mbp.dwStyle = uType | MB_USERICON;
mbp.dwLanguageId = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
mbp.lpfnMsgBoxCallback = NULL;
mbp.dwContextHelpId = 0;
mbp.lpszIcon = MAKEINTRESOURCE(uIconResID);

return MessageBoxIndirect(&mbp);
}

// ... usage example
int nRet = CustomMessageBox(m_hWnd, _T("TEXT"), _T("Caption"), MB_OKCANCEL, IDI_ICON1);

mapna
November 28th, 2006, 09:57 AM
Heaps of thanks for the quick replies! That's something i was trying to do but had no idea of the details..

-Ilkka

mapna
November 28th, 2006, 12:55 PM
I got the custom icon working, thanks for the help!

Now i'm facing another problem: my message box function is in a .dll file, which i want to import and use in an application. The custom icon works fine if i load the icon resource and launch the MessageBoxIndirect in the app, but if i do it in the .dll, the icon wont' show up at all.

Is there any way to solve this without importing the icon resource from the .dll to the application and loading it there? I would like to load the icon and launch the message box in the .dll function, so that all i need to do in the application is to call my imported ShowCustomMessageBox(CString msgText) method. It doesn't feel very user-friendly to import all the resources also from the .dll.

This is probably a simple issue, but seems that it's too much for me...

Thanks in advance,

Ilkka

VladimirF
November 28th, 2006, 02:23 PM
Now i'm facing another problem: my message box function is in a .dll file, which i want to import and use in an application. The custom icon works fine if i load the icon resource and launch the MessageBoxIndirect in the app, but if i do it in the .dll, the icon wont' show up at all.
Try changing yourmbp.hInstance = GetModuleHandle(NULL); to point to the instance of that DLL.

mapna
November 28th, 2006, 04:20 PM
What do you know, that was exactly what i needed to do. Works fine, thanks a lot!