Where do i find standard system icons of messageboxes via WinApi? - c

Where do i find standard system icons of messageboxes via WinApi? I want to create an advanced dialogbox (with details-extension) as WinApi resource, but I want to use the system default icons like:
For .NET I know that i'll find them in System.Drawing.SystemIcons, but where do I find them using native C and WinApi? And how could I apply them?

You should be able to get them using LoadIcon. To get the question mark icon use LoadIcon(NULL, IDI_QUESTION), the other identifiers are IDI_ERROR, IDI_WARNING and IDI_INFORMATION.

Thats correct,
If someone needs here my code to set the icon and also to play the corresponding sound.
HICON hIcon = NULL;
if(mbdIcon == MBD_ICON_INFORMATION) {
hIcon = LoadIcon(NULL, IDI_INFORMATION);
MessageBeep(MB_ICONASTERISK);
} else if(mbdIcon == MBD_ICON_QUESTION) {
hIcon = LoadIcon(NULL, IDI_QUESTION);
MessageBeep(MB_ICONQUESTION);
} else if(mbdIcon == MBD_ICON_WARNING) {
hIcon = LoadIcon(NULL, IDI_WARNING);
MessageBeep(MB_ICONWARNING);
} else if(mbdIcon == MBD_ICON_ERROR) {
hIcon = LoadIcon(NULL, IDI_ERROR);
MessageBeep(MB_ICONERROR);
} else {
ShowWindow(hPictureIcon, SW_HIDE);
}
if(hIcon != NULL)
{
Static_SetIcon(hPictureIcon, hIcon);
}
May it saves someone some minutes. :)

Related

Standard icons set in C with Win32

I am looking for the normal way (that is, the way Microsoft thought about when creating its API) to load standard icons for commands in a pure C program, like the floppy disc image for saving, etc.
The Internet doesn't seem to contain the answer. I know the toolbars of commctl32 can receive a TB_LOADIMAGES message that fills an image list with standard icons, but what if I don't need toolbars in my app? I want icons in another control, let's say on an owner-draw button, or a menu item. Is there a way to fill the image list without creating a useless toolbar? Or even better, getting HICON or HBITMAP handles to avoid the commctl32 dependency?
The loud silence about it in Microsoft's docs, and on the web, makes me think there is no such feature. Maybe when an application is developed with Microsoft tools, the application creator injects as resources in the executable files the default icons the developer chooses in a predefined list? I cannot check it because I only use Unix-like compilers, can somebody confirm that and/or tell me more about default icon usage under Windows?
Also, would it be reliable to assume we can load libraries like shell32.dll to use its embedded icons (like all the good old functions that are available since an eternity in kernel32.dll, `user32.dll, ...)? I mean, is there a guarantee that icons in libraries will keep their semantics and indexes in future versions of Windows?
Coming some days later to post the final solution I opted for, just in case somebody would need to use the same. The most normal way to show command icons is to embed them in the application, so despite being unhappy with the creation of a dummy control, I use a temporary toolbar to load the icons in global image lists. This would unlikely fail, but since icons may sometimes be the only thing that indicates to the user what a widget does, I reinforced the conditions with the ability to run a fallback code when something is wrong.
The function that loads the icons is named WIN32_initIcons(), because it is supposed to be implemented alongside with something like a GTK_initIcons() or X11_initIcons() counterpart for Unix-like platforms.
HIMAGELIST WIN32_imglst16 = NULL;
HIMAGELIST WIN32_imglst24 = NULL;
bool WIN32_initIcons(void) {
bool def16 = false;
bool def32 = false;
HWND hWnd;
WIN32_imglst16 = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 80, 16);
WIN32_imglst32 = ImageList_Create(24, 24, ILC_COLOR32 | ILC_MASK, 80, 16);
if (hWnd = CreateWindowA("ToolbarWindow32", NULL, TBSTYLE_LIST, 0, 0, 0, 0, NULL, (HMENU)0, GetModuleHandle(NULL), NULL)) {
if (WIN32_imglst16) {
SendMessage(hWnd, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)WIN32_imglst16);
if (!SendMessage(hWnd, TB_LOADIMAGES, (WPARAM)IDB_STD_SMALL_COLOR, (LPARAM)HINST_COMMCTRL)) def16 = true;
if (SendMessage(hWnd, TB_LOADIMAGES, (WPARAM)IDB_VIEW_SMALL_COLOR, (LPARAM)HINST_COMMCTRL) != 15) def16 = false;
if (SendMessage(hWnd, TB_LOADIMAGES, (WPARAM)IDB_HIST_SMALL_COLOR, (LPARAM)HINST_COMMCTRL) != 27) def16 = false;
if (ImageList_GetImageCount(WIN32_imglst16) != 32) def16 = false;
}
if (WIN32_imglst24) {
SendMessage(hWnd, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)WIN32_imglst24);
if (!SendMessage(hWnd, TB_LOADIMAGES, (WPARAM)IDB_STD_SMALL_COLOR, (LPARAM)HINST_COMMCTRL)) def24 = true;
if (SendMessage(hWnd, TB_LOADIMAGES, (WPARAM)IDB_VIEW_SMALL_COLOR, (LPARAM)HINST_COMMCTRL) != 15) def24 = false;
if (SendMessage(hWnd, TB_LOADIMAGES, (WPARAM)IDB_HIST_SMALL_COLOR, (LPARAM)HINST_COMMCTRL) != 27) def24 = false;
if (ImageList_GetImageCount(WIN32_imglst24) != 32) def24 = false;
}
DestroyWindow(hWnd);
}
if (WIN32_imglst16 && !def16) {
// Load your custom 16x16 fallback icons in the list "WIN32_imglst16" here
// Don't forget to set "def16 = true" on success
}
if (WIN32_imglst24 && !def24) {
// Load your custom 24x24 fallback icons in the list "WIN32_imglst24" here
// Don't forget to set "def24 = true" on success
}
if (!def16) {
// Trigger your error management here because 16x16 icons cannot be loaded
// Maybe, call "ImageList_Destroy(WIN32_imglst16)" and set "WIN32_imglst16 = NULL"
}
if (!def24) {
// Trigger your error management here because 24x24 icons cannot be loaded
// Maybe, call "ImageList_Destroy(WIN32_imglst24)" and set "WIN32_imglst24 = NULL"
}
return (def16 && def24);
}
Note: In simple C, use <stdbool.h> to define the bool value.

Problem to identify the window handle and window name of a UIelement

Objective: I am using the library Uiautomation.h to retrieve the window handle (hwnd) and window name when the user clicks on one element of that window. I need a solution with plain C.
Example: If the User clicks on the button 8 of the windows calculator, I need to identify the window handle and name as follow:
I am retrieving no window when the user clicks into a element of the windows calculator:
hwnd = 0
Window name = none
I am retrieving always 0 as hwnd. However, when I click in the header of the window, I can retrieve the hwnd and the window name as "Calculator". This is part of my code in plain C:
UIA_HWND hwnd;
PWSTR win_name = NULL;
static int win_len;
POINT pt;
IUIAutomation *pAutomation = NULL;
IUIAutomationElement *element = NULL;
CoInitialize(NULL);
EXTERN_C const CLSID CLSID_CUIAutomation;
EXTERN_C const IID IID_IUIAutomation;
HRESULT hr = CoCreateInstance(&CLSID_CUIAutomation,NULL, CLSCTX_INPROC_SERVER,&IID_IUIAutomation,(void**)&pAutomation);
GetCursorPos(&pt);
hr = IUIAutomation_ElementFromPoint(pAutomation, pt, &element);
if(SUCCEEDED(hr) && element != NULL){
IUIAutomationElement_get_CurrentNativeWindowHandle(element,&hwnd);
win_len = GetWindowTextLengthW(hwnd);
if(win_len > 0) {
win_name = (PWSTR) malloc(sizeof(wchar_t) * win_len + 1);
GetWindowTextW(hwnd, win_name, win_len + 1);
}
}
I used also the function hwnd = GetForegroundWindow(); but I still get the same value 0. Could someone know what I am doing incorrectly?

CreateDialog returning 0 but getting ERROR_SUCCESS

The following code returns 0 to wnd but right after the CreateDialog the error is ERROR_SUCCESS. The dialog doesn't show up and I don't understand how this is possible. It's a console project and the dialog is created in vs2013, if that's relevant.
#include <windows.h>
#include "resource.h"
int main(){
HWND wnd = CreateDialog(NULL, MAKEINTRESOURCE(IDD_DIALOG1), NULL, NULL);
ShowWindow(wnd, SW_SHOWDEFAULT);
UpdateWindow(wnd);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
This has to be some really stupid mistake but I can't see it.
You'll need to initialise the rich edit library first - if the library isn't loaded, the control won't be registered and the dialog creation will fail.
See the note at http://msdn.microsoft.com/en-us/library/windows/desktop/hh298375(v=vs.85).aspx about calling LoadLibrary. You need to do this before creating the dialog.
Alternatively setting the DS_NOFAILCREATE style should allow the dialog to be created although the rich edit control won't show up.
Had same exact problem my Dialog wouldn't appear it was in-fact missing the RichText2.0 Control load up.
This is how I fixed it should support any windows version.
Add this include to your project
#include <richedit.h> // To use richedit control
//Load RichText4.1 or 2.0/3.0 or 1.0 (last resort) Control first. (3 different DLL's for full support).
//
// FUNCTION: IsWinXPSp1Min()
//
// PURPOSE: Return TRUE if operating sytem is Windows XP SP1 or later.
// Windows XP SP1 is the minimum system required to use a richedit v4.1 but only
// when UNICODE is defined.
//
BOOL IsWinXPSp1Min()
{
OSVERSIONINFO osvi = { sizeof(osvi) };
if (!GetVersionEx(&osvi))
{
return FALSE;
}
// Determine if system is Windows XP minimum
if (osvi.dwMajorVersion >= 5 && osvi.dwMinorVersion >= 1)
{
// Now check if system is specifically WinXP and, if so, what service pack
// version is installed.
if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1)
{
// The following test assumes that the szCSDVersion member of the
// OSVERSIONINFO struct's format will always be a string like
// "Service Pack x", where 'x' is a number >= 1. This is fine for SP1
// and SP2 but future service packs may have a different string
// descriptor.
TCHAR* pszCSDVersion = L"Service Pack 1";
if (osvi.szCSDVersion < pszCSDVersion)
{
return FALSE;
}
}
return TRUE;
}
return FALSE;
}
//
// FUNCTION: GetRichEditClassName()
//
// PURPOSE: Load the proper version of RichEdit and return the class name.
//
PCWSTR GetRichEditClassName()
{
HINSTANCE hLib;
// Try to load latest version of rich edit control. Since v4.1 is available
// only as an UNICODE control on a minimum of Windows XP with service pack 1
// installed, use preprocessor conditional to ensure that an attempt to load
// Msftedit.dll is only made if UNICODE is defined.
#if defined UNICODE
if (IsWinXPSp1Min())
{
// Try to get richedit v4.1, explicitly use wide character string as this
// is UNICODE only.
hLib = LoadLibrary(L"msftedit.dll");
if (hLib)
{
return MSFTEDIT_CLASS;
}
}
#endif
// Cannot get latest version (v4.1) so try to get earlier one
// Rich Edit Version 2.0/3.0
hLib = LoadLibrary(L"riched20.dll");
if (hLib)
{
// Version 2.0/3.0 is good
return RICHEDIT_CLASS;
}
// Rich Edit Version 1.0
hLib = LoadLibrary(L"riched32.dll");
if (hLib)
{
// Version 1.0 is good
return L"RichEdit";
}
// Cannot get any versions of RichEdit control (error)
return L"";
}
resource.h file
#define IDC_RICHEDIT 3990
Create the actual RichEdit control
// // FUNCTION: OnInitRichEditDialog(HWND, HWND, LPARAM) // // PURPOSE: Process the WM_INITDIALOG message // BOOL OnInitRichEditDialog(HWND hWnd, HWND hWndFocus, LPARAM lParam) {
RECT rc = { 20, 20, 160, 250 };
HWND hRichEdit = CreateWindowEx(WS_EX_CLIENTEDGE, GetRichEditClassName(),
L"RichEdit Control",
ES_MULTILINE | ES_AUTOHSCROLL | WS_HSCROLL | ES_AUTOVSCROLL |
WS_VSCROLL | WS_CHILD | WS_VISIBLE,
rc.left, rc.top, rc.right, rc.bottom,
hWnd, reinterpret_cast<HMENU>(IDC_RICHEDIT), g_hInst, 0);
if (hRichEdit)
{
SendMessage(hRichEdit, WM_SETFONT, reinterpret_cast<WPARAM>(g_hFont), TRUE);
}
return TRUE; }

GeckoFX - WinForms - javascript:print()

i just created a win form app
with a Gecko.GeckoWebBrowser on it
when i navigate to a page with a anchor that has the href attribute set to
javascript:print() and click on it, the print dialog is displayed, but it turns out that when i hit cancel button on that dialog
the Gecko.GeckoWebBrowser is destroyed , i mean the control receives a WM_DETROY message
any clue of what is could be happen here?
how i can prevent it?
i modified the gecko fx Gecko.GeckoWebBrowser windows procedure and catch and bypass that windows message but it seems that is not helping
btw i am using xulrunner-11.0.en-US.win32 and geckofx-11.dll
regards
From looking at the firefox code, It looks like firefox is sending the WM_DESTROY message.
nsPrintingPromptService::ShowPrintDialog(nsIDOMWindow *parent, nsIWebBrowserPrint *webBrowserPrint, nsIPrintSettings *printSettings)
{
NS_ENSURE_ARG(parent);
HWND hWnd = GetHWNDForDOMWindow(parent);
NS_ASSERTION(hWnd, "Couldn't get native window for PRint Dialog!");
return NativeShowPrintDialog(hWnd, webBrowserPrint, printSettings);
}
nsresult NativeShowPrintDialog(HWND aHWnd,
nsIWebBrowserPrint* aWebBrowserPrint,
nsIPrintSettings* aPrintSettings)
{
PrepareForPrintDialog(aWebBrowserPrint, aPrintSettings);
nsresult rv = ShowNativePrintDialog(aHWnd, aPrintSettings);
if (aHWnd) {
::DestroyWindow(aHWnd);
}
return rv;
}
I'm not sure why it would do this.
Some options to fix this:
turn on "print.always_print_silent"
provide and register your own nsIPrintingPromptService
provide and register your own nsIWindowWatcher service.
The nsIWindowWatcher way looks like the proper way to do this looking at GetHWNDForDOMWindow:
HWND
nsPrintingPromptService::GetHWNDForDOMWindow(nsIDOMWindow *aWindow)
{
nsCOMPtr<nsIWebBrowserChrome> chrome;
HWND hWnd = NULL;
// We might be embedded so check this path first
if (mWatcher) {
nsCOMPtr<nsIDOMWindow> fosterParent;
if (!aWindow)
{ // it will be a dependent window. try to find a foster parent.
mWatcher->GetActiveWindow(getter_AddRefs(fosterParent));
aWindow = fosterParent;
}
mWatcher->GetChromeForWindow(aWindow, getter_AddRefs(chrome));
}
if (chrome) {
nsCOMPtr<nsIEmbeddingSiteWindow> site(do_QueryInterface(chrome));
if (site)
{
HWND w;
site->GetSiteWindow(reinterpret_cast<void **>(&w));
return w;
}
}

Not able to display the progress bar using threading concept?

I am trying to show a progress bar while my process is going on...in my application there will be a situation where I gotta read files and manipulate them(it will take some time to complete)..want to display a progress bar during this operation..the particular function I am calling is an win 32 ...so if you check my code below ...I am able to display the progressbar but it doesnt show any progress..actually its not doing any further process...Please help me..thanks in advance
//my function
int Myfunction(....)
{
MSG msg;
HWND dialog = CreateWindowEx(0,WC_DIALOG,L"Proccessing...",WS_OVERLAPPEDWINDOW|WS_VISIBLE,
600,300,280,120,NULL,NULL,NULL,NULL);
HWND pBar = CreateWindowEx(NULL,PROGRESS_CLASS,NULL,WS_CHILD|WS_VISIBLE,40,20,200, 20,
dialog,(HMENU)IDD_PROGRESS,NULL,NULL);
SendMessage(pBar,PBM_SETRANGE,0,MAKELPARAM(0,noOfFile));
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
Dispatch(&message);
}
HANDLE getHandle = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)SetFilesForOperation(...),
NULL,NULL,0);
}
LPARAM SetFilesForOperation(...)
{
for(int index = 0;index < noOfFiles; index++)
{
*checkstate = *(checkState + index);
if(*checkstate == -1)
{
*(getFiles+i) = new TCHAR[MAX_PATH];
wcscpy(*(getFiles+i),*(dataFiles +index));
i++;
}
else
{
(*tempDataFiles)->Add(*(dataFiles+index));
*(checkState + localIndex) = *(checkState + index);
localIndex++;
}
PostMessage(pBar,PBM_SETPOS,(WPARAM)index,0);
}
}
I suspect the problem is that you're creating the thread after your app exits - if you move the call to CreateThread above the message pump it may work better.
I prefer to use QT over MFC. Here's how I would use it to answer your question:
Use form designer to create a dialog, and use AfxBeginThread(someFunc, param) to create a thread.
In someFunc, use SendMessage to tell the dialog about the progress.
sample here:
http://www.tek-tips.com/faqs.cfm?fid=5162

Resources