Почему мое контекстное (всплывающее) меню в WinAPI не отображается? - PullRequest
0 голосов
/ 09 марта 2012

Я пытаюсь настроить контекстное меню, используя 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 Ответ

1 голос
/ 09 марта 2012

Ваш hMenu является статической переменной, которая загружается до того, как hInst имеет значение. Я считаю, что LoadMenu вызов не работает.

Вы также заметите в документации TrackPopupMenu , что можно использовать не просто любой дескриптор меню, это должен быть дескриптор всплывающего меню. В ресурсах создайте отдельный элемент для меню верхнего уровня и поместите под ним всплывающее меню; затем используйте LoadMenu, чтобы загрузить верхний уровень, и GetSubMenu, чтобы получить дескриптор вашего раскрывающегося списка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...