-
Nothing's happening!
I wrote a program that should change the highlight color of my window's menus.
here is the code:
Code:
//This is a practice program: How to make OWNER_DRAWN menus
//Written by Alexis Georges
//Translated from a VB demo from PSC
#include <windows.h>
HMENU hMenu; //our top-menu
HMENU hPopupMenu1; //pop-up menu attached to the top-menu
//menu ID's
#define ID_FIRST 40001
#define ID_SECOND 40002
#define ID_COLOR1 40003 //blue
#define ID_COLOR2 40004 // green
#define ID_COLOR3 40005 //red
//vars
static char g_szClassName[] = "OD Menus - Practice 1";
static HINSTANCE g_hInst = NULL; //storage for the instance of the program
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam,
LPARAM lParam)
{
LPDRAWITEMSTRUCT di;
LPMEASUREITEMSTRUCT ms;
SIZE sz;
HDC hdc;
switch(Message) {
case WM_CREATE:
{
hMenu = CreateMenu();
hPopupMenu1 = CreatePopupMenu();
AppendMenu(hPopupMenu1, MF_STRING | MF_OWNERDRAW,ID_FIRST, "First");
AppendMenu(hPopupMenu1, MF_STRING | MF_OWNERDRAW,ID_SECOND, "Second");
AppendMenu(hPopupMenu1, MF_STRING | MF_OWNERDRAW,ID_COLOR1, "Color 1");
AppendMenu(hPopupMenu1, MF_STRING | MF_OWNERDRAW,ID_COLOR2, "Color 2");
AppendMenu(hPopupMenu1, MF_STRING | MF_OWNERDRAW,ID_COLOR3, "Color 3");
AppendMenu(hMenu,MF_POPUP,(unsigned int)hPopupMenu1,"Voila");
SetMenu(hwnd, hMenu);
DrawMenuBar(hwnd);
UpdateWindow(hwnd);
}
break;
case WM_DRAWITEM:
{
//catch the passing of the structure
di = (LPDRAWITEMSTRUCT)lParam;
HBRUSH use_brush;
HFONT use_font;
HFONT old_font;
LOGFONT lf;
RECT use_rect;
RECT top_rect;
COLORREF color;
if(di->itemState == ODS_SELECTED)
{
switch(di->itemID)
{
case ID_FIRST:
{
color = RGB(00,00,00);
use_brush = CreateSolidBrush(color);
}
case ID_SECOND:
{
color = RGB(22,00,00);
use_brush = CreateSolidBrush(color);
}
default:
use_brush = CreateSolidBrush(GetSysColor(COLOR_MENU));
}
//fill the region with the created brush
FillRect(di->hDC, &di->rcItem, use_brush);
//we can now delete the brush
if(use_brush)
DeleteObject(use_brush);
}
else
//non-selected text color
use_brush = CreateSolidBrush(GetSysColor(COLOR_MENU));
if(di->itemState == ODS_SELECTED)
{
color = RGB(00,00,00);
switch(di->itemID)
{
case ID_COLOR1:
SetTextColor(di->hDC,color);
case ID_COLOR2:
SetTextColor(di->hDC,color);
case ID_COLOR3:
SetTextColor(di->hDC,color);
}
}
else
SetTextColor(di->hDC,color);
SetBkMode(di->hDC, TRANSPARENT);
use_rect = di->rcItem ; //popup menu
top_rect = di->rcItem ; //top menu
use_rect.left = use_rect.left + 16;
//get the cur. font
old_font = (HFONT)SelectObject(di->hDC, GetStockObject(SYSTEM_FONT));
GetObject(old_font, sizeof(lf), &lf);
lf.lfPitchAndFamily = FF_DONTCARE;
lf.lfWeight = 400;
use_font = CreateFontIndirect(&lf); //create our font;
//select it
SelectObject(di->hDC, use_font);
//set corners of the regions
use_rect.left = use_rect.left + 5;
use_rect.top = use_rect.top + 3;
top_rect.left = top_rect.left + 5;
top_rect.top = top_rect.top + 2;
//now, let's draw the text :)
switch(di->CtlID)
{
case ID_FIRST:
DrawText(di->hDC,"First", 4, &top_rect, DT_LEFT | DT_TOP | DT_SINGLELINE);
case ID_SECOND:
DrawText(di->hDC,"Second", 6, &use_rect, DT_LEFT | DT_TOP | DT_SINGLELINE);
case ID_COLOR1:
DrawText(di->hDC,"Color 1", 7, &use_rect, DT_LEFT | DT_TOP | DT_SINGLELINE);
case ID_COLOR2:
DrawText(di->hDC,"Color 2", 7, &use_rect, DT_LEFT | DT_TOP | DT_SINGLELINE);
case ID_COLOR3:
DrawText(di->hDC,"Color 3", 7, &use_rect, DT_LEFT | DT_TOP | DT_SINGLELINE);
}
SelectObject(di->hDC,old_font);
if(use_font)
DeleteObject(old_font);
}
break;
case WM_MEASUREITEM:
{
//dc of our main window
hdc = GetDC(hwnd);
ms = (LPMEASUREITEMSTRUCT)lParam;
if(ms->CtlType == ODT_MENU)
{
//set initial(or default) values
ms->itemHeight = 20;
ms->itemWidth = 60;
//get size from string
if((ms->itemID == ID_FIRST) || (ms->itemID == ID_SECOND))
{
GetTextExtentPoint32(hdc,"SECOND",lstrlen("SECOND"), &sz);
ms->itemHeight = sz.cy;
ms->itemWidth = sz.cx;
}
else if((ms->itemID == ID_COLOR1) || (ms->itemID == ID_COLOR2) ||
(ms->itemID == ID_COLOR3))
{
GetTextExtentPoint32(hdc, "Color 3",lstrlen("Color 3"), &sz);
ms->itemHeight = sz.cy;
ms->itemWidth = sz.cx;
}
}
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,Message,wParam,lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASSEX WndClass;
HWND hwnd;
MSG msg;
g_hInst = hInstance;
WndClass.cbSize = sizeof(WNDCLASSEX);
WndClass.style = NULL;
WndClass.lpfnWndProc = WndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = g_hInst;
WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW);
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = g_szClassName;
WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&WndClass)) {
MessageBox(0, "Window Registration Failed!","Error",
MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);
return 0;
}
//create the main window
hwnd = CreateWindowEx(
WS_BORDER,
g_szClassName,
"OD Menus - Practice 1",
WS_MINIMIZEBOX | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT, 320, 135,
NULL, NULL, g_hInst, NULL);
//check for null handle
if(hwnd == NULL) {
MessageBox(0, "Window Creation Failed", "Error",
MB_ICONEXCLAMATION | MB_OK | MB_SYSTEMMODAL);
return 0;
}
ShowWindow(hwnd, nShowCmd);
UpdateWindow(hwnd);
//message loop
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
I was just playing around, so a few things might be useless, but when I compile the program, it says there are noerrors, and no warnings. The problem is that my menus are blank except for the top level menu, under that, there is no text or item, just a blank window droping down. Could someone help me(I can't figure it out :(
Thanks in advance :)
-
Remove | MF_OWNERDRAW from your AppendMenu
-
hmm...
Thanks Technocrat, but now it simply displays normal menus. just as if all the stuff was not there :(
-
Sorry did not pay attention to your question.
Hang on let me run through it.
-
Ok I am getting closer
The first thing I am noticing is that you do not have a default color. So you might want to put color = to something at the start of WM_DRAWITEM.
Second change:
switch(di->CtlID) to:
switch(di->itemID)
Finally, I am still working this one out, but your if statements in WM_DRAWITEM never run.
-
That's pretty weird. I looked on the MSDN to see what to use, and the ODS_SELECTED was there. :) now, why wouldn't the program go through it?!
-
Ok here is last couple of things for ya, I got to go back to work on my stuff now.
First of all you need to put break; in each of your case statements. Thats a big no no to leave those out ;)
Finally change:
if(di->itemState == ODS_SELECTED) to:
if(di->itemState & ODS_SELECTED)
and that will work now.
Its not perfect but at least it should get you started back on the right track.
-
great!!!
Thanks a lot Technocrat. Now i had to put back the MF_OWNERDRAW flags, and I also have to fix my menu modification, thanks a lot :) My first owner-drawn menus ! :)
Amon Ra
-
No problem, glad to help.
-
there...
There, I just finished it, and it workd perfectly fine :) Thanks. Now I can play around with the color , size... :)
Amon Ra
-
Lemme know when you are done with it, I would be interested in checking out the final product. Kinda cool :)
-
:)
No prob. I will post it when complete. BTW, what is the address of your site? thanks
Amon Ra