I don't knof if that's the right place, since it's not c++ specific but a windows development doubt...
(and sorry my english)

My problem is kinda stupid, but i don't know whats happening, im tryng to show a popup menu when user press the righ mouse buttom, in the cursor position, the problem is it shows up far away from the cursor position, but ever in the same position from the mouse..

Im in a windows 2000 SP4, using Visual Studio 2005 pro, win 32 application

My code is a mess..im just praticing windows programin for the first time..

void DisplayPopupMenu(long x, long y){
	GetSystemMetrics(SM_MENUDROPALIGNMENT);//determine the correct horizontal alignment flag (TPM_LEFTALIGN or TPM_RIGHTALIGN) 
	HMENU temp= GetSubMenu(PopupMenu,0);
	TrackPopupMenu(temp,TPM_LEFTALIGN|TPM_RIGHTBUTTON,x,y,0,Window,NULL);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
	switch(msg){
		case WM_DESTROY: PostQuitMessage(0);break;//when 'X' is clicked: quit application(sends a WM_QUIT)
		case WM_COMMAND: WMCommand(hWnd, msg, wParam, lParam);break;//function to buttons(listed ^up)
		case WM_RBUTTONUP: DisplayPopupMenu(LOWORD(lParam), HIWORD(lParam)); break;
			                          //WM_RBUTTONUP : actived when mouse right button is released( it uses iParam to
			                         //obtain x an y of the mouse, to get those we need the macro LOWORD(to x) andHIWORD(to y))
			
		}
		return(DefWindowProc(hWnd, msg, wParam, lParam));
	}

Thats the part of the code what do the popup menu stuff, but I don't know if you need more stuff to see, so I will post the entire code:

#include <windows.h>
//#include <winbase.h>
#include "resource.h"



HMENU PopupMenu;
HMENU Menu;
HWND Window;
HWND b_CreateWall;//just as normal windows interface, buttons are handles of a window

const int width=640;//screen width and height
const int height=480;
const int b_width=100;//button width and height
const int b_height=20;


//its a good idea create a function for WM_COMMAND, cause the msg handler(WndProc) will clutter
//if i make it all with 'case:'
//same parameters of the handler
//converts b_CreateWall to LPARAM e compare with lParam, if its the same, a buttom is clicked
void WMCommand(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
	if(lParam==(LPARAM)b_CreateWall) MessageBoxA(Window,"apertou 'b_CreateWall'","botao",MB_OK);
	
	else if(wParam==ID_FILE_EXIT40003)PostQuitMessage(0);//if clicked exit on file menu

	else if(wParam==ID_DRAWING_WIREFRAME){//if clicked it
		CheckMenuItem(Menu,ID_DRAWING_WIREFRAME,MF_CHECKED);
		CheckMenuItem(Menu,ID_DRAWING_SOLID,MF_UNCHECKED);
	}
	else if(wParam==ID_DRAWING_SOLID){
		CheckMenuItem(Menu,ID_DRAWING_SOLID,MF_CHECKED);
		CheckMenuItem(Menu,ID_DRAWING_WIREFRAME,MF_UNCHECKED);
	}

	//popup menu:
	else if(wParam==ID_POPUP_MOVE) MessageBoxA(Window,"apertou 'Move'","clicked",MB_OK);
	else if(wParam==ID_POPUP_DUPLICATE) MessageBoxA(Window,"apertou 'Duplicate'","clicked",MB_OK);
	else if(wParam==ID_POPUP_DELETE) MessageBoxA(Window,"apertou 'Delete'","clicked",MB_OK);
	else if(wParam==ID_POPUP_TEXTURE) MessageBoxA(Window,"apertou 'Texture'","clicked",MB_OK);
}

void DisplayPopupMenu(long x, long y){
	GetSystemMetrics(SM_MENUDROPALIGNMENT);//determine the correct horizontal alignment flag (TPM_LEFTALIGN or TPM_RIGHTALIGN) 
	HMENU temp= GetSubMenu(PopupMenu,0);
	TrackPopupMenu(temp,TPM_LEFTALIGN|TPM_RIGHTBUTTON,x,y,0,Window,NULL);
}

// the message handler
 //(handle to the current window, type of message being sent,additional info about message being sent,
 // additional info about message being sent)
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
	switch(msg){
		case WM_DESTROY: PostQuitMessage(0);break;//when 'X' is clicked: quit application(sends a WM_QUIT)
		case WM_COMMAND: WMCommand(hWnd, msg, wParam, lParam);break;//function to buttons(listed ^up)
		case WM_RBUTTONUP: DisplayPopupMenu(LOWORD(lParam), HIWORD(lParam)); break;
			                          //WM_RBUTTONUP : actived when mouse right button is released( it uses iParam to
			                         //obtain x an y of the mouse, to get those we need the macro LOWORD(to x) andHIWORD(to y))
			
		}
		return(DefWindowProc(hWnd, msg, wParam, lParam));
	}
	//The DefWindowProc function will  ensure that all messages are processed 
	//either through their respective message handler or through a default message
	//same parameters from WndProc callback


// main XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR IpCmdLine,int nShowCmd){
	
	WNDCLASS wc;
	MSG msg;//message

	//register a window class
	wc.cbClsExtra=0;                                       //extra bytes of memory for the wndclass size
	wc.cbWndExtra=0;                                       //extra bytes for the windows instance
	wc.hbrBackground=(HBRUSH)GetStockObject(LTGRAY_BRUSH);//sets the background color
	wc.hCursor=LoadCursor(NULL, IDC_ARROW);               //sets the cursor for the window(current instance,ID of cursor)
	wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);//sets the icon for the application(// , // of the icon)
	//We set this first parameter as NULL to indicate we want to use the standard
    //Windows icons/cursors rather than specifying custom resources
	wc.hInstance=hInstance;                              //requires the handle of the instance( witch is hInstance from WinMain)
	wc.lpfnWndProc=WndProc;                               //pointer to the window procedure, our message handler
	wc.lpszClassName=L"TESTANDO";                        //the class name
	wc.lpszMenuName=NULL;                                //controls the menu that is to be loaded for the window class
	wc.style= CS_OWNDC|CS_HREDRAW|CS_VREDRAW;            //CS_HREDRAW and CS_VREDRAW,will redraw the screen when 
	                                                     //the width or height of the client window has been changed,and CS_OWNDC,
	                                                     //which gives each registered class a unique device context

	//now i have to register the class
	//if succefull a diferent of 0 number will return
	//if error, it will return 0
	if(!RegisterClass(&wc)){
		MessageBoxA(NULL,"DEU PAU!!! Nao registro a classe", "TAQUIUPARIU!!!", MB_OK);
		return 0;
	}

	//now create the window
	//WS_OVERLAPPEDWINDOW: creates a window with max and min buttons
	//WS_VISIBLE: allow windows to be visible uppon creation
	//x and y coordinates
	//hWndParent:NULL cause this is the parent, used just when a child must be created
	//hMenu: load menu, but at now i dont need
	//current instance
	//multiple-document interface (MDI)-?complex stuff
	Window=CreateWindowA("TESTANDO","Teste WinApi",WS_OVERLAPPEDWINDOW|WS_VISIBLE,100,100,640,480,
		                 NULL,NULL,hInstance,NULL);

	//create button
	//(BUTTON to it know its a button,name,that will be a child not an independent window
	//any window only parameter here will be diregarded,x,y,w,h,the parent(created just before)
	b_CreateWall=CreateWindowA("BUTTON","Criar Parede",WS_CHILD|WS_VISIBLE,0,100,b_width,b_height,
		                      Window,NULL,hInstance,NULL);
	Menu     =LoadMenu(hInstance,MAKEINTRESOURCEW(IDR_MENU1));
	SetMenu(Window,Menu);

	PopupMenu=LoadMenu(hInstance,MAKEINTRESOURCEW(IDR_MENU2));
	//test
	if(Window==NULL){
		MessageBoxA(NULL,"IHH,NAO DEU PRA CRIA WINDOW","Pau na janela",MB_OK);
		return 0;
	}

	//now the main loop

	
	//peek message
	//message address,handle of the window we are getting messages from,range of the messages
	//we can use,range of the messages we can use(0 default),PM_NOREMOVE, which	does not remove 
	//the message from the message queue, and PM_REMOVE,
	//if theres no data on the qeue, it returns 0
	//If the message is not WM_QUIT, then we must call the TranslateMessage and Dispatch-
	//Message functions, which will translate a message from virtual keypresses to
	//character messages and dispatch the new message to the window procedure.
	while(1){
		if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
			if(msg.message==WM_QUIT) break;
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}



	return 1;
}

By the way, the popup menu is working, the problem is just the position..

Recommended Answers

All 2 Replies

Your problem is very small :) The coordinate in which you are trying to display the menu is not based on the client location. Change your WM_RBUTTONUP message like this:

case WM_RBUTTONUP: 
   POINT p;
   p.x = LOWORD(lParam);
   p.y = HIWORD(lParam);
   ClientToScreen(hWnd, &p);
   DisplayPopupMenu(p.x, p.y);
   break;

Hope this helps.

Yeah, it works perfectly! o.o
Tanx a lot man!!

But, do you know what was that my wrong code was returning as x and y before? Im curious.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.