Popup Menu and OpenGL

Hello everyone! Whenever I change the background color from the popup menu, part of the menu remains on the window. Does anyone know why and how that can be fixed? The code is enclosed below. Any help is appreciated as well, ;-).

X3J16

#include <windows.h>
#include <gl\gl.h>

#define WND_X_POS 20
#define WND_Y_POS 20

#define WND_HEIGHT 480
#define WND_WIDTH 400

#define WHITE_BKGND 0
#define BLACK_BKGND 1

#define IDM_BKGND_WHITE 100
#define IDM_BKGND_BLACK 101
#define IDM_APP_EXIT 102

static LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);

static const char g_szWndClsName[] = “my_window_class”;
static const char g_szWndCaption[] = “;-)”;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pszCmdLine, int iShowCmd)
{
WNDCLASS wc;
HWND hwnd;
MSG msg;

wc.style	 = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc	 = MainWndProc;
wc.cbClsExtra	 = 0;
wc.cbWndExtra	 = 0;
wc.hInstance	 = hInstance;
wc.hIcon	 = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor	 = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName	 = NULL;
wc.lpszClassName = g_szWndClsName;

RegisterClass(&wc);

hwnd = CreateWindow(g_szWndClsName, g_szWndCaption,
		    WS_OVERLAPPEDWINDOW,
		    WND_X_POS, WND_Y_POS,
		    WND_WIDTH, WND_HEIGHT,
		    NULL, NULL, hInstance, NULL);

ShowWindow(hwnd, iShowCmd);
UpdateWindow(hwnd);

while (GetMessage(&msg, NULL, 0, 0)) {
	TranslateMessage(&msg);
	DispatchMessage(&msg);
}

return msg.wParam;

}

static HMENU CreateOpenGLPopupMenu(VOID);
static VOID SetWindowPixelFormat(HDC);
static VOID RenderOpenGLFace(HDC, UCHAR);

static LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HMENU hPopupMenu = NULL;
static HDC hDC = NULL;
static HGLRC hGLRC = NULL;

static UCHAR BkgndColor = WHITE_BKGND;

POINT  pt;

switch (uMsg) {
case WM_CREATE:
	hDC	   = GetDC(hWnd);
	SetWindowPixelFormat(hDC);
	hGLRC	   = wglCreateContext(hDC);   /* Create OpenGL rendering context and */
	wglMakeCurrent(hDC, hGLRC);	      /* make it current for this thread.    */
	
	hPopupMenu = CreateOpenGLPopupMenu();

	return 0;

case WM_SIZE:
	glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0.0F, 1.0F, 0.0F, 1.0F, -1.0F, 1.0F);

	return 0;

case WM_PAINT:
	RenderOpenGLFace(hDC, BkgndColor);
	ValidateRect(hWnd, NULL);

	return 0;

case WM_RBUTTONUP:
	pt.x = LOWORD(lParam);
	pt.y = HIWORD(lParam);
	ClientToScreen(hWnd, &pt);
	TrackPopupMenu(hPopupMenu, TPM_LEFTBUTTON, pt.x, pt.y,
		       0, hWnd, NULL);

	return 0;

case WM_COMMAND:
	switch (LOWORD(wParam)) {
	case IDM_BKGND_WHITE:
		BkgndColor = WHITE_BKGND;
		CheckMenuItem(hPopupMenu, IDM_BKGND_BLACK, MF_UNCHECKED);
		CheckMenuItem(hPopupMenu, IDM_BKGND_WHITE, MF_CHECKED);

		break;

	case IDM_BKGND_BLACK:
		BkgndColor = BLACK_BKGND;
		CheckMenuItem(hPopupMenu, IDM_BKGND_WHITE, MF_UNCHECKED);
		CheckMenuItem(hPopupMenu, IDM_BKGND_BLACK, MF_CHECKED);

                    break;

	case IDM_APP_EXIT:
		SendMessage(hWnd, WM_CLOSE, 0, 0);
		
		return 0;

	default:
		break;
	}

	InvalidateRect(hWnd, NULL, FALSE);

	return 0;

case WM_KEYDOWN:
	if (wParam == VK_ESCAPE)
		SendMessage(hWnd, WM_CLOSE, 0, 0);

	break;

case WM_DESTROY:
	wglMakeCurrent(NULL, NULL);      /* Detach the current rendering context */
	wglDeleteContext(hGLRC);	 /* from the thread and delete it.       */

	ReleaseDC(hWnd, hDC);
	DestroyMenu(hPopupMenu);

	PostQuitMessage(0);

	return 0;

default:
	break;
}

return DefWindowProc(hWnd, uMsg, wParam, lParam);

}

static HMENU CreateOpenGLPopupMenu(VOID)
{
struct {
UINT uFlags;
UINT uItemID;
PCSTR pszMenuText;
} MenuOptions[] = {
MF_STRING | MF_CHECKED, IDM_BKGND_WHITE, “White Background”,
MF_STRING, IDM_BKGND_BLACK, “Black Background”,
MF_SEPARATOR, 0, NULL,
MF_STRING, IDM_APP_EXIT, “Exit”
};

HMENU hPopupMenu;
int   i;

hPopupMenu = CreatePopupMenu();

for (i = 0; i &lt; sizeof MenuOptions / sizeof MenuOptions[0]; ++i)
	AppendMenu(hPopupMenu, 
		   MenuOptions[i].uFlags,
		   MenuOptions[i].uItemID,
		   MenuOptions[i].pszMenuText);

return hPopupMenu;

}

static VOID SetWindowPixelFormat(HDC hDC)
{
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), /* Size of this pfd /
1, /
Version number /
PFD_DRAW_TO_WINDOW | /
Support window /
PFD_SUPPORT_OPENGL | /
Support OpenGL /
PFD_DOUBLEBUFFER, /
Double buffered /
PFD_TYPE_RGBA, /
RGBA type /
24, /
24-bit color depth /
0, 0, 0, 0, 0, 0, /
Color bits ignored /
0, /
No alpha buffer /
0, /
Shift bit ignored /
0, /
No accumulation buffer /
0, 0, 0, 0, /
Accum bits ignored /
32, /
32-bit z-buffer /
0, /
No stencil buffer /
0, /
No auxiliary buffer /
PFD_MAIN_PLANE, /
Main layer /
0, /
Reserved /
0, 0, 0 /
Layer masks ignored */
};

int	iPixelFormat;

/*
   Get the device context's best available pixel format match and make
   that match the device context's current pixel format.
*/
iPixelFormat = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, iPixelFormat, &pfd);

}

static VOID RenderOpenGLFace(HDC hDC, UCHAR BkgndColor)
{
static const GLfloat WhiteBkgndColor[3] = { 1.0F, 1.0F, 1.0F },
BlackBkgndColor[3] = { 0.0F, 0.0F, 0.0F };

if (BkgndColor == WHITE_BKGND)
	glClearColor(WhiteBkgndColor[0], WhiteBkgndColor[1], WhiteBkgndColor[2], 0.0F);
else
	glClearColor(BlackBkgndColor[0], BlackBkgndColor[1], BlackBkgndColor[2], 0.0F);

glClear(GL_COLOR_BUFFER_BIT);

glFlush();

SwapBuffers(hDC);

}

I tested your code. The menu disappeared as expected. It did appear to linger for a moment after the background color switched, but that is fairly normal. Maybe try TPM_NOANIMATION in the TrackPopupMenu if that is what you were talking about.

If not what version of Windows? What Graphics Card? I am on Win2k using GF2.

Shinpaughp,

Thank you for testing my code, but, in my case, the menu does disappear and only the selected menu option remains (after the background color is switched) until I resize or cover the window (i.e. a new WM_PAINT message is sent to the window procedure). I’m on Windows XP using GF3 and VC++ 6.0. As for the flag you suggested, it’s not documented in my MSDN library. Anyway, thank you once again for helping me.

X3J16

Originally posted by shinpaughp:
[b]I tested your code. The menu disappeared as expected. It did appear to linger for a moment after the background color switched, but that is fairly normal. Maybe try TPM_NOANIMATION in the TrackPopupMenu if that is what you were talking about.

If not what version of Windows? What Graphics Card? I am on Win2k using GF2.[/b]

You may want to try changing your menu fade settings from fade effect to scroll effect or turn off the transition effects for menus and tooltips. Go to Display control panel, go to Effects tab, first item is “Use transition effects for menues and tooltips”. See if changing that or turning it off has some effect. By turning it off, on Win2k, the menu disappeared immediately before the change of background. And you should be able to use SystemParameterInfo to change it from within your application and change it back before exiting so anyone else using your app on another computer with XP won’t have the same problem… hopefully.

I have a Geforce 3 and Windows XP, and the above code worked flawlessly. What driver version are you using? I’m using 41.09 reference drivers.

DeFrey,
How are your transition effects set?

And, X3J16, how are yours set?

I have the menu and tooltip transition effect set to fade.

Sorry, then, I have no clue. Could be anything. Try updating Windows through Windows Update - see if there is something affecting GDI and as DeFrey said update your drivers.

Almost forgot, I also have Windows XP Service Pack 1 installed too.

[This message has been edited by DFrey (edited 02-15-2003).]

Guys,

Thanks a lot! I originally had a transition effect for menus and tooltips set to fade effect, and changing it to scroll effect or turning it off completely solved the problem. However, I’m not sure if I should change any settings for the duration of my program (plus I didn’t find any option to change these setting in my MSDN Library, but, I guess, it’s out of date. Shinpaughp, what values are you suggesting using for the uiAction parameter?). Are there any other ways to solve this problem on another user’s computer?

And my System Information viewer tells me that I have NVIDIA GeForce3 Ti 200 Driver Version 2.1.8.5 dated on 09/19/2001. I’m new to Windows programming, so could you, please, post any good links that explain everything about graphics hardware and software?

Anyway, thanks for responding to this message to both of you!

X3J16

First, since your driver is out of date, go to www.nvidia.com and download the latest drivers for windows xp. Shut down all applications and run the .exe updater. Restart even if it doesn’t tell you to. Try your program again.

Unfortunately, the specific flags I was thinking of do not appear to be supported under VC6. It is supported under VC7.Net. I was going to suggest that uiAction should be either SPI_GETMENUFADE to retrieve the state or SPI_SETMENUFADE to set the state. And there is also SPI_GETSELECTIONFADE and SPI_SETSELECTIONFADE which affect the fading of the chosen menu item after the rest of the menu disappears.


Found it!!! There is also the master switch which is equivalent to turning on/off the feature completely as SPI_GETMENUANIMATION and SPI_SETMENUANIMATION. It is supported under VC6.