WINAPI/C++ wID abitrary number?

Home built / K9a2 cf-f
June 13, 2010 at 00:02:03
Specs: Windows XP, Athlon xp x2 64 5600 / 2gb
Basically I'm trying to finish something I started a
while ago, it's very simple but has been a bit of trouble....

All it is for is toggling the console close button from
enabled to disabled and visa-versa but I'm not sure if using
the window handle for wID is safe or recommended. It works but
I'm just not sure....

If it's not can anyone recommend a better way of doing this?

[compiled on] Mingw 3.14(Devpak) via Dev-c++

#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <iostream>

int main(int argc, char *argv[])
    if (argc == 1)
        return 1;
    UINT revokeid = (unsigned int)GetConsoleWindow();
    close.cbSize = sizeof(MENUITEMINFO);
    close.fMask = MIIM_STATE|MIIM_ID;
    close.fState = MFS_GRAYED;
    //Despite being wID msdn claims it's an UINT
    close.wID = revokeid;
    if (argv[1][0] == '1')
         if (!SetMenuItemInfo(GetSystemMenu(GetConsoleWindow(), FALSE), SC_CLOSE, FALSE, &close))
             std::cerr << "Failed API call" << std::endl;
             return 1;
    } else {
        close.fState = MFS_ENABLED;
        close.wID = SC_CLOSE;
         if (!SetMenuItemInfo(GetSystemMenu(GetConsoleWindow(), FALSE), revokeid, FALSE, &close))
             std::cerr << "Failed API call" << std::endl;
             return 1;
    return 0;

BTW: This is not how I will be parsing the arguments,
that part is just to facilitate an independent example.

Thanks to anyone that has a look into it.

See More: WINAPI/C++ wID abitrary number?

Report •

June 13, 2010 at 00:21:19
I forgot to mention that what I meant by the title is that *any* arbitrary number as wID does the trick so long as it doesn't overlap constants like "SC_CLOSE". If I pass back SC_CLOSE then the console can re-enable the menu on <alt>+<space> or icon click....

MSDN links:


Even it somebody could post a link to some useful info, because I can find any and the description is rather vague:

An application-defined value that identifies the menu item.

Report •

June 13, 2010 at 13:35:20
Seems that any number < 0xf000 will do the trick without overlapping predefined values, I settled for 0x0fa0 because none the headers use that value for anything.

If anyone is interested in the program, here's a link: Swcde 2.2

Report •

June 22, 2010 at 10:59:29
This topic's old, but I've been gone and now I'm back, so whatever.

I meant by the title is that *any* arbitrary number as wID does the trick so long as it doesn't overlap constants like "SC_CLOSE".
This is true. Your confusion is because you haven't run a Win32 message pump. Whatever you set wID to be, you'll have to watch for that ID in your message pump. (It comes across as the low word of wParam.)

A very quick and dirty example of what I'm talking about (Win32 app, from Dev-C++, no less):

#include <windows.h>
#include <cstdio>

const unsigned wID = 5; //Change this to see different output.


char szClassName[ ] = "Win32 Message Test";

int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance,
                   LPSTR lpszArgument, int show) {
    HWND hwnd;               
    MSG message;            

    WNDCLASSEX wincl;        
	wincl.cbSize = sizeof(WNDCLASSEX);
	wincl.cbClsExtra = 0;
	wincl.cbWndExtra = 0;

    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;   = CS_DBLCLKS;                
    wincl.hIcon = LoadIcon (0, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (0, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (0, IDC_ARROW);
    wincl.lpszMenuName = 0;
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    if (!RegisterClassEx (&wincl))
        return 0;

    hwnd = CreateWindowEx (0, szClassName, "Windows App", WS_OVERLAPPEDWINDOW,
	                       CW_USEDEFAULT,  CW_USEDEFAULT, 544, 375, 
						   HWND_DESKTOP, 0, hThisInstance, 0);
    //Add a new menu item
    char menuItemName[] = "Click Me";
    HMENU sysMenu = GetSystemMenu(hwnd, false);
    item.cbSize = sizeof(item);
    item.fType = MFT_SEPARATOR;
    item.fState = MFS_ENABLED;
    item.wID = wID + 1;
	InsertMenuItem(sysMenu, SC_CLOSE, false, &item);
	item.fType = MFT_STRING;
	item.wID = wID;
    item.dwTypeData = menuItemName;
    item.cch = sizeof(menuItemName);
	if (!InsertMenuItem(sysMenu, wID + 1, false, &item)) {
		MessageBox(0, "InsertMenu #1 failed", 0, MB_OK|MB_ICONSTOP);
		return 1;
	ShowWindow(hwnd, show);

    while (GetMessage(&message, 0, 0, 0)) {
    return message.wParam;

//Called by the Windows function DispatchMessage()
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, 
                                  WPARAM wParam, LPARAM lParam) {
    switch (message) {
        case WM_DESTROY:
        case WM_SYSCOMMAND: //Because we added our item to the System Menu, 
			if (wParam == wID) { //and not our own menu.
				char str[44];
				std::sprintf(str, "The ID is: %d", wID);
				MessageBox(hwnd, str, "", MB_OK);
            return DefWindowProc (hwnd, message, wParam, lParam);
    return 0;

Report •

Related Solutions

June 22, 2010 at 14:26:30
Thanks razor,

Nice clear example of a message pump, interestingly enough it would fault(window or console project on xp home sp3) until I commented out this line:

InsertMenuItem(sysMenu, SC_CLOSE, false, &item);

It's not strictly what I'm after, but I can learn a lot from it so it's helpful none the less.

All I was trying to do was disable and re-enable the console close button without screwing up the order or removing the bitmap.

Unless I changed wID right clicking on the title bar or <alt>+<space> would re-enable it when disabled. I was really just trying to affirm a safe value of wIDm not to to hook it or anything, just to ensure that it was properly disabled.

Thanks again!

Report •

Ask Question