Code:
#include <windows.h>
//Just some definitions that we will use later on to
//create the popup menu
#define IDM_WHITE 4001
#define IDM_LTGRAY 4002
#define IDM_GRAY 4003
#define IDM_DKGRAY 4004
#define IDM_BLACK 4005
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {
HWND hwnd;
MSG msg;
WNDCLASS wc;
TCHAR szAppName[] = TEXT("PopMenu");
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = szAppName;
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;
if(!RegisterClass(&wc)) {
MessageBox(NULL, TEXT("Could not register class"), szAppName, MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szAppName, TEXT("Popup Menu Demo"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
static HMENU hMenu;
static int idColor[5] = {WHITE_BRUSH, LTGRAY_BRUSH, GRAY_BRUSH, DKGRAY_BRUSH, BLACK_BRUSH };
static int iSelection = IDM_WHITE;
POINT point;
switch(message) {
case WM_CREATE:
//All this does is creates the menu dynamically. I did this so I wouldn't have to worry about uploading a resource
//script. It performs the same function. Note for a resource script you will have to explicitley say it is a
//popup menu.
hMenu = CreatePopupMenu();
AppendMenu(hMenu, MF_STRING, IDM_WHITE, "White");
AppendMenu(hMenu, MF_STRING, IDM_LTGRAY, "Light Gray");
AppendMenu(hMenu, MF_STRING, IDM_GRAY, "Gray");
AppendMenu(hMenu, MF_STRING, IDM_DKGRAY, "Dark Gray");
AppendMenu(hMenu, MF_STRING, IDM_BLACK, "Black");
return 0;
case WM_RBUTTONUP:
//The popupmenu will be displayed when the user right clicks so for this example I chose to track it with the
//right button up message
point.x = LOWORD(lParam); // fugure out where the mouse was when the user clicked
point.y = HIWORD(lParam); //
ClientToScreen(hwnd, &point); //conver those coordinates into screen coordinates (relative -> absolute)
TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, point.x , point.y ,0, hwnd, NULL); //Display the popup menu and inform
//windows we want to track the right mouse button.
return 0;
case WM_COMMAND:
switch(LOWORD(wParam)) {
case IDM_WHITE:
case IDM_LTGRAY:
case IDM_GRAY:
case IDM_DKGRAY:
case IDM_BLACK:
//This is just some menu handling logic that checks the menu item and then redraws the background.
//Nothing really unique here.
CheckMenuItem(hMenu, iSelection, MF_UNCHECKED);
iSelection = LOWORD(wParam);
CheckMenuItem(hMenu, iSelection, MF_CHECKED);
SetClassLong(hwnd, GCL_HBRBACKGROUND, (LONG)GetStockObject(idColor[(LOWORD(wParam) - IDM_WHITE)]));
InvalidateRect(hwnd, NULL, TRUE);
return 0;
}
break;
case WM_DESTROY:
DestroyMenu(hMenu);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}