Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

popup menu ain't workin(popup menu on right click not working)

red888red888 Member Posts: 25
I know there is something very basic here I am missing, but I can't figure it out. This program compiles fine (didn't include Resource.h & Resources1.rc cause I think the issue is elsewhere), but when I right click in the window no popup menu appears.

As an aside I'd like to create a function for the popup menu, like the menubar function "AddMenus", but whenever I tried that it didn't work (putting it in the PopupProc). I'd like to know how to make that work too.

Thank you to whoever answers this thread. I'm am very new to this so consider me mildly retarded when you formulate an explain of why this isn't working like I want it to.



[code]
#include
#include "resource.h"

LPCTSTR ClsName = L"BasicApp";
LPCTSTR WndName = L"A Simple Window";

LRESULT CALLBACK WndProcedure(HWND hwnd, UINT uMsg,WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK PopupProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );


void AddMenus(HWND);


INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
HWND hwnd;
MSG Msg;
WNDCLASSEX WndClsEx;

WndClsEx.cbSize = sizeof(WNDCLASSEX);
WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
WndClsEx.lpfnWndProc = WndProcedure;
WndClsEx.cbClsExtra = 0;
WndClsEx.cbWndExtra = 0;
WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClsEx.hCursor = LoadCursor(hInstance,MAKEINTRESOURCE(IDC_TARGET));
WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
WndClsEx.lpszMenuName = NULL;
WndClsEx.lpszClassName = ClsName;
WndClsEx.hInstance = hInstance;
WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

RegisterClassEx(&WndClsEx);

hwnd = CreateWindow(ClsName,
WndName,
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);

if( !hwnd )
return 0;

ShowWindow(hwnd, SW_SHOWNORMAL);
UpdateWindow(hwnd);

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

return Msg.wParam;
}


LRESULT CALLBACK WndProcedure(HWND hwnd, UINT Msg,WPARAM wParam, LPARAM lParam)
{
switch(Msg)
{
case WM_CREATE:
AddMenus(hwnd);
break;

case WM_COMMAND:
switch(LOWORD(wParam)) {
case IDM_FILE_NEW:
case IDM_FILE_OPEN:
Beep(50, 100);
break;
case IDM_FILE_QUIT:
SendMessage(hwnd, WM_CLOSE, 0, 0);
break;
}
break;

case WM_DESTROY:
PostQuitMessage(WM_QUIT);
break;
default:
return DefWindowProc(hwnd, Msg, wParam, lParam);
}
return 0;
}



LRESULT CALLBACK PopupProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
HMENU hMenu;
POINT point;
switch(msg)
{
case WM_RBUTTONUP:
point.x = LOWORD(lParam);
point.y = HIWORD(lParam);
hMenu = CreatePopupMenu();
ClientToScreen(hwnd, &point);

AppendMenu(hMenu, MF_STRING, IDM_FILE_NEW, TEXT("&New"));
AppendMenu(hMenu, MF_STRING, IDM_FILE_OPEN, TEXT("&Open"));
AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
AppendMenu(hMenu, MF_STRING, IDM_FILE_QUIT, TEXT("&Quit"));

TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, point.x, point.y, 0, hwnd, NULL);
DestroyMenu(hMenu);
break;

case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}


void AddMenus(HWND hwnd) {
HMENU hMenubar;
HMENU hMenu;

hMenubar = CreateMenu();
hMenu = CreateMenu();

AppendMenu(hMenu, MF_STRING, IDM_FILE_NEW, L"&New");
AppendMenu(hMenu, MF_STRING, IDM_FILE_OPEN, L"&Open");
AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
AppendMenu(hMenu, MF_STRING, IDM_FILE_QUIT, L"&Quit");

AppendMenu(hMenubar, MF_POPUP, (UINT_PTR)hMenu, L"&File");
SetMenu(hwnd, hMenubar);
}
[/code]

Comments

  • AsmGuru62AsmGuru62 Member Posts: 6,519
    [color=Blue]The [italic]PopupProc[/italic] is never used in your code. Also, [b]PostQuitMessage(...)[/b] should be used only once per single-threaded application.[/color]
  • red888red888 Member Posts: 25
    So how do I use PopupProc in my code? Like I said there is something basic here that I'm missing. Do I need to reference it somehow in WinMain?

    Thanks
  • AsmGuru62AsmGuru62 Member Posts: 6,519
    [code]
    #include
    #include "resource.h"

    LPCTSTR ClsName = L"BasicApp";
    LPCTSTR WndName = L"A Simple Window";

    LRESULT CALLBACK WndProcedure(HWND hwnd, UINT uMsg,WPARAM wParam, LPARAM lParam);
    LRESULT CALLBACK PopupProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam );


    void AddMenus(HWND);


    INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
    {
    HWND hwnd;
    MSG Msg;
    WNDCLASSEX WndClsEx;

    WndClsEx.cbSize = sizeof(WNDCLASSEX);
    WndClsEx.style = CS_HREDRAW | CS_VREDRAW;
    WndClsEx.lpfnWndProc = WndProcedure;
    WndClsEx.cbClsExtra = 0;
    WndClsEx.cbWndExtra = 0;
    WndClsEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    WndClsEx.hCursor = LoadCursor(hInstance,MAKEINTRESOURCE(IDC_TARGET));
    WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClsEx.lpszMenuName = NULL;
    WndClsEx.lpszClassName = ClsName;
    WndClsEx.hInstance = hInstance;
    WndClsEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    RegisterClassEx(&WndClsEx);

    hwnd = CreateWindow(ClsName,
    WndName,
    WS_OVERLAPPEDWINDOW | WS_VISIBLE,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    CW_USEDEFAULT,
    NULL,
    NULL,
    hInstance,
    NULL);

    if( !hwnd )
    return 0;

    ShowWindow(hwnd, SW_SHOWNORMAL);
    UpdateWindow(hwnd);

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

    return Msg.wParam;
    }


    LRESULT CALLBACK WndProcedure(HWND hwnd, UINT Msg,WPARAM wParam, LPARAM lParam)
    {
    switch(Msg)
    {
    case WM_CREATE:
    AddMenus(hwnd);
    break;

    [color=Green]// You can do it in two ways:
    //
    // 1. You can simply reroute the message WM_RBUTTONUP to your
    // other procedure - which is what I did.
    //
    // 2. Or you can simply implement (copy/paste) same code
    // here - in this same window procedure - see commented code below.[/color]
    [color=Red]case WM_RBUTTONUP:
    CallWindowProc (PopupProc, hwnd, Msg, wParam, lParam);
    break;[/color]

    [color=Green] /*
    case WM_RBUTTONUP:
    {
    HMENU hMenu = CreatePopupMenu();
    POINT point;
    GetCursorPos (&point);

    AppendMenu(hMenu, MF_STRING, IDM_FILE_NEW, TEXT("&New"));
    AppendMenu(hMenu, MF_STRING, IDM_FILE_OPEN, TEXT("&Open"));
    AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
    AppendMenu(hMenu, MF_STRING, IDM_FILE_QUIT, TEXT("&Quit"));

    TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, point.x, point.y, 0, hwnd, NULL);
    DestroyMenu(hMenu);
    }
    break;
    */[/color]

    case WM_COMMAND:
    switch(LOWORD(wParam)) {
    case IDM_FILE_NEW:
    case IDM_FILE_OPEN:
    Beep(50, 100);
    break;
    case IDM_FILE_QUIT:
    SendMessage(hwnd, WM_CLOSE, 0, 0);
    break;
    }
    break;

    case WM_DESTROY:
    PostQuitMessage(WM_QUIT);
    break;
    default:
    return DefWindowProc(hwnd, Msg, wParam, lParam);
    }
    return 0;
    }



    LRESULT CALLBACK PopupProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
    {
    HMENU hMenu;
    POINT point;
    switch(msg)
    {
    case WM_RBUTTONUP:
    point.x = LOWORD(lParam);
    point.y = HIWORD(lParam);
    hMenu = CreatePopupMenu();
    ClientToScreen(hwnd, &point);

    AppendMenu(hMenu, MF_STRING, IDM_FILE_NEW, TEXT("&New"));
    AppendMenu(hMenu, MF_STRING, IDM_FILE_OPEN, TEXT("&Open"));
    AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
    AppendMenu(hMenu, MF_STRING, IDM_FILE_QUIT, TEXT("&Quit"));

    TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, point.x, point.y, 0, hwnd, NULL);
    DestroyMenu(hMenu);
    break;

    case WM_DESTROY:
    PostQuitMessage(0);
    break;
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
    }


    void AddMenus(HWND hwnd) {
    HMENU hMenubar;
    HMENU hMenu;

    hMenubar = CreateMenu();
    hMenu = CreateMenu();

    AppendMenu(hMenu, MF_STRING, IDM_FILE_NEW, L"&New");
    AppendMenu(hMenu, MF_STRING, IDM_FILE_OPEN, L"&Open");
    AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
    AppendMenu(hMenu, MF_STRING, IDM_FILE_QUIT, L"&Quit");

    AppendMenu(hMenubar, MF_POPUP, (UINT_PTR)hMenu, L"&File");
    SetMenu(hwnd, hMenubar);
    }
    [/code]
  • red888red888 Member Posts: 25
    Awesome! Thank you so much for the extremely quick responses. I was really confused about that, but it makes perfect sense now. So if I have multiple callback procedures, and additional or child windows my main window procedure for the program has to know about them right?
  • carlycarly Member Posts: 46
    No, it's wrong.
    Popup menu is WM_CONTEXTMENU
    Read MSDN...
Sign In or Register to comment.