为什么我的WinAPI中的上下文(弹出)菜单没有出现?

时间:2012-03-08 23:24:54

标签: c++ winapi

我正在尝试在我的应用程序中使用WinAPI设置上下文菜单,但由于某种原因我没有成功。弹出菜单的代码放在WM_RBUTTONUP案例中。但是,右键单击后没有任何反应。有人能告诉我我做错了什么吗?

的.cpp:

#include "stdafx.h"
#include "Growing_children_PAWEL_MICHNA.h"

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;                                // current instance
TCHAR szTitle[MAX_LOADSTRING];                  // The title bar text
//TCHAR szChild1Title[MAX_LOADSTRING];
//TCHAR szChild2Title[MAX_LOADSTRING];
TCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name
TCHAR szChild1WindowClass[MAX_LOADSTRING];
TCHAR szChild2WindowClass[MAX_LOADSTRING];

HWND hWnd, child1hWnd, child2hWnd;
HMENU hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_CONTEXT_MENU));

int mywidth = 25;
int myheight = 25;
bool greater = true;
// Forward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
ATOM                Child1RegisterClass(HINSTANCE hInstance);
ATOM                Child2RegisterClass(HINSTANCE hInstance);

BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    MSG msg;
    HACCEL hAccelTable;

    // Initialize global strings
    LoadString(hInstance, IDS_APP_TITLE, NULL, MAX_LOADSTRING);
    LoadString(hInstance, IDC_GROWING_CHILDREN_PAWEL_MICHNA, szWindowClass, MAX_LOADSTRING);
    LoadString(hInstance, IDC_CHILD1, szChild1WindowClass, MAX_LOADSTRING);
    LoadString(hInstance, IDC_CHILD2, szChild2WindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);
    Child1RegisterClass(hInstance);
    Child2RegisterClass(hInstance);

    // Perform application initialization:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_GROWING_CHILDREN_PAWEL_MICHNA));

    // Main message loop:
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    HBRUSH redBrush = CreateSolidBrush(RGB(255, 0, 0));
    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = NULL; //CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_GROWING_CHILDREN_PAWEL_MICHNA));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = redBrush;
    wcex.lpszMenuName   = MAKEINTRESOURCE(NULL);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassEx(&wcex);
}

ATOM Child1RegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    HBRUSH blueBrush = CreateSolidBrush(RGB(0, 0, 255));
    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_PARENTDC; //CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_GROWING_CHILDREN_PAWEL_MICHNA));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = blueBrush;
    wcex.lpszMenuName   = MAKEINTRESOURCE(NULL);
    wcex.lpszClassName  = szChild1WindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassEx(&wcex);
}

ATOM Child2RegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    HBRUSH greenBrush = CreateSolidBrush(RGB(0, 255, 0));
    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_PARENTDC; //CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_GROWING_CHILDREN_PAWEL_MICHNA));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground  = greenBrush;
    wcex.lpszMenuName   = MAKEINTRESOURCE(NULL);
    wcex.lpszClassName  = szChild2WindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindowEx(WS_EX_TOPMOST | WS_EX_LAYERED, szWindowClass, NULL, WS_POPUPWINDOW, CW_USEDEFAULT, 0, 500, 500, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   // Set windows transparency to 70%
   SetLayeredWindowAttributes(hWnd, 0, (255 * 70) / 100, LWA_ALPHA);

   RECT rc; 

   // get the center of the work area of the system 
   SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, 0); 
   int centerX = (rc.left + rc.right + 1) / 2; 
   int centerY = (rc.top + rc.bottom + 1) / 2; 

   //move the main windows to the center
   MoveWindow(hWnd, centerX-250, centerY-250, 500, 500, true);

   child1hWnd = CreateWindow(szChild1WindowClass, NULL, WS_CHILD, 0, 0, 25, 25, hWnd, NULL, hInstance, NULL);
   SetLayeredWindowAttributes(child1hWnd, 0, (255 * 70) / 100, LWA_ALPHA);

   child2hWnd = CreateWindow(szChild2WindowClass, NULL, WS_CHILD, 475, 476, 25, 25, hWnd, NULL, hInstance, NULL);
   SetLayeredWindowAttributes(child2hWnd, 0, (255 * 70) / 100, LWA_ALPHA);

   ShowWindow(hWnd, nCmdShow);
   ShowWindow(child1hWnd, nCmdShow);
   ShowWindow(child2hWnd, nCmdShow);

   UpdateWindow(hWnd);
   UpdateWindow(child1hWnd);
   UpdateWindow(child2hWnd);

   return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
    POINT point;

    switch (message)
    {
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
        case IDM_ABOUT:
            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;
    case WM_CREATE:
    {
        SetTimer(hWnd, 1, 100, NULL);
        return 0; 
    }
        break;
    case WM_RBUTTONUP: 
    {
        point.x = LOWORD(lParam); 
        point.y = HIWORD(lParam); 

        ClientToScreen(hWnd, &point); 
        TrackPopupMenu(hMenu, TPM_RIGHTBUTTON, point.x, point.y, 0, hWnd, NULL); 
        return 0;
    }
    case WM_TIMER:
        if(mywidth < 250 && greater == true)
        {
            MoveWindow(child1hWnd, 0, 0, ++mywidth, ++myheight, true);
            MoveWindow(child2hWnd, 500-mywidth, 500-myheight, mywidth, myheight, true);
            if(mywidth == 250)
                greater = false;
        }
        else
        {
            MoveWindow(child1hWnd, 0, 0, --mywidth, --myheight, true);
            MoveWindow(child2hWnd, 500-mywidth, 500-myheight, mywidth, myheight, true);
            if(mywidth == 0)
                greater = true;
        }
        break;
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_NCHITTEST:
        if (hWnd == child1hWnd || hWnd == child2hWnd) return HTTRANSPARENT;
        return HTCAPTION; 
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}

.rc片段:

IDR_CONTEXT_MENU MENU
BEGIN
    MENUITEM "Color",                       ID_COLOR32778
    POPUP "Figures"
    BEGIN
        MENUITEM "None",                        ID_FIGURES_NONE, CHECKED
        MENUITEM "Square",                      ID_FIGURES_SQUARE
        MENUITEM "Triangle",                    ID_FIGURES_TRIANGLE
        MENUITEM "Circle",                      ID_FIGURES_CIRCLE
    END
    MENUITEM "Exit",                        ID_EXIT
END

1 个答案:

答案 0 :(得分:1)

您的hMenu是一个静态变量,在hInst具有值之前加载。我认为LoadMenu电话失败了。

您还会在TrackPopupMenu documentation中注意到,不仅可以使用任何菜单句柄,它还必须是弹出菜单句柄。在资源中,为顶级菜单创建一个元素,并将弹出菜单放在其下面;然后使用LoadMenu加载顶级,并使用GetSubMenu来获取下拉列表的句柄。