Menampilkan Pop up menu

Untuk menampilkan popup menu dalam program yang dibuat dengan <windows.h>, kita bisa menggunakan TrackPopupMenu. Berbeda dengan SetMenu yang digunakan untuk menempatkan menu di menu bar, TrackPopupMenu bisa menampilkan menu di posisi tertentu dalam windows.

Menu bisa kita tampilkan saat ada event tertentu. Pada tulisan saya kali ini, program yang akan kita buat menampilkan menu saat ada event klik kanan.

Kita harus menggunakan GetSubMenu jika menunya dibuat dengan CreateMenu. GetSubmenu bisa kita gunakan untuk mendapatkan submenu atau bagian dari menu berdasarkan index-nya. Jika kita ingin mendapatkan semua bagian dari menu, maka kita gunakan menu pada index ke-0.

#include <windows.h>

HWND wind;
HMENU hmenu, pmenu, anak;

LRESULT CALLBACK wndproc(
  HWND hwnd,
  UINT pesan,
  WPARAM wParam,
  LPARAM lParam
);


int __stdcall WinMain(HINSTANCE hinst, HINSTANCE hprev, char *cmdl, int cmds){
MSG msg;
WNDCLASS wcls={0};
    wcls.hInstance=hinst;
    wcls.hbrBackground=GetSysColorBrush(COLOR_3DFACE);
    wcls.lpszClassName=TEXT("windowku");
    wcls.lpfnWndProc=wndproc;
    wcls.hCursor=LoadCursor(0,IDC_ARROW);

    RegisterClass(&wcls);

    wind=CreateWindowEx(0, TEXT("windowku"), "Programku", WS_VISIBLE | WS_OVERLAPPEDWINDOW , 400, 200, 198, 300, 0, 0, hinst, 0);

    pmenu=CreateMenu();
    anak=CreateMenu();
    AppendMenu(anak, MF_STRING, 101, "Ubah");
    AppendMenu(pmenu, MF_STRING, 102, "FILE");
    AppendMenu(pmenu, MF_POPUP, (UINT_PTR)anak, "EDIT");
   
    hmenu=CreateMenu();
    AppendMenu(hmenu, MF_POPUP, (UINT_PTR)pmenu, "MENUKU");

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

    return msg.wParam;
}

LRESULT CALLBACK wndproc(HWND hwnd, UINT pesan, WPARAM wParam, LPARAM lParam){
POINT pos;
int x;
    switch(pesan){
        case WM_RBUTTONDOWN:
            GetCursorPos(&pos);
            TrackPopupMenu(GetSubMenu(hmenu, 0), 0, pos.x, pos.y, 0, wind, 0);
            break;
        case WM_COMMAND:
            x=LOWORD(wParam);
            if(x==101){
                MessageBox(hwnd, "101", "Menu", MB_OK);
            }else if(x==102){
                MessageBox(hwnd, "102", "Menu", MB_OK);
            }
            break;
        case WM_CLOSE:
            PostQuitMessage(0);
            break;

    }

    return DefWindowProc(hwnd, pesan, wParam, lParam);
}


Dari contoh di atas, kita bisa melihat beberapa event. Event klik kanan konstantanya adalah WM_RBUTTONDOWN.  Selain itu ada event WM_COMMAND yang dipicu saat menu atau tombol diklik.

Untuk mendapatkan posisi kursor kita bisa menggunakan GetCursorPos. Tipe data dari parameter function GetCursorPos adalah POINT. POINT memiliki x dan y sebagai anggotanya. x dan y akan menerima koordinat dari function GetCursorPos.

Jika kita tidak ingin menggunakan GetSubMenu, menunya harus dibuat dengan CreatePopupMenu.

#include <windows.h>

HWND wind;
HMENU pmenu, anak;

LRESULT CALLBACK wndproc(
  HWND hwnd,
  UINT pesan,
  WPARAM wParam,
  LPARAM lParam
);


int __stdcall WinMain(HINSTANCE hinst, HINSTANCE hprev, char *cmdl, int cmds){
MSG msg;
WNDCLASS wcls={0};
    wcls.hInstance=hinst;
    wcls.hbrBackground=GetSysColorBrush(COLOR_3DFACE);
    wcls.lpszClassName=TEXT("windowku");
    wcls.lpfnWndProc=wndproc;
    wcls.hCursor=LoadCursor(0,IDC_ARROW);

    RegisterClass(&wcls);

    wind=CreateWindowEx(0, TEXT("windowku"), "Programku", WS_VISIBLE | WS_OVERLAPPEDWINDOW , 400, 200, 198, 300, 0, 0, hinst, 0);

    pmenu=CreatePopupMenu();
    anak=CreateMenu();
    AppendMenu(anak, MF_STRING, 101, "Ubah");
    AppendMenu(pmenu, MF_STRING, 102, "FILE");
    AppendMenu(pmenu, MF_POPUP, (UINT_PTR)anak, "EDIT");

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

    return msg.wParam;
}

LRESULT CALLBACK wndproc(HWND hwnd, UINT pesan, WPARAM wParam, LPARAM lParam){
POINT pos;
int x;
    switch(pesan){
        case WM_RBUTTONDOWN:
            GetCursorPos(&pos);
            TrackPopupMenu(pmenu, 0, pos.x, pos.y, 0, wind, 0);
            break;
        case WM_COMMAND:
            x=LOWORD(wParam);
            if(x==101){
                MessageBox(hwnd, "101", "Menu", MB_OK);
            }else if(x==102){
                MessageBox(hwnd, "102", "Menu", MB_OK);
            }
            break;
        case WM_CLOSE:
            PostQuitMessage(0);
            break;

    }

    return DefWindowProc(hwnd, pesan, wParam, lParam);
}