// JP opened flex table

Click to See Complete Forum and Search --> : How to reposition the menu?


Kansana
April 27th, 2007, 01:47 AM
Hi All,

I have a menu which is normally displayed at the left bottom of an icon in the UI(the UI is displayed at the rigth side of the screen). I use TrackPopUpMenu to display the window.

My requirement is that when the 'menu width' exceeds that of the width(calculated between the top-left of the menu icon and the rigth end of the desktop window) , I have to display the menu at the right bottom of the icon. At present, I handle the WM_INITMENUPOPUP . In that I calculate the widths and try to reposition the menu.I used SetWindowPos,MoveWindow but still I get the menu displayed at the left bottom of the icon. Please let me know how to reposition the menu. Also please let me know whether my approach is correct.

Please find below the code snippet

case WM_INITMENUPOPUP:
{
HMENU hMenu;
hMenu = GetMenu (this->GetHwnd());
int nMenuWidth = 0;
int nMenuHeight = 0;
RECT rct;
int nScreenWidth = 0;
int nWidth = 0;
BOOL bRet = false;
HWND hWndMenu = FindWindow(L"#32768", NULL);

LONG nMenuSize = (LONG)SendMessage((HWND)hWndMenu, 0x01E2, 1, 0);

nMenuWidth = LOWORD(nMenuSize) + GetSystemMetrics(SM_CXFIXEDFRAME) * 2;

nMenuHeight = HIWORD(nMenuSize) + GetSystemMetrics(SM_CYFIXEDFRAME) * 2;

nScreenWidth = GetSystemMetrics(SM_CXFULLSCREEN);
::GetWindowRect(m_btnMenu.GetHwnd(), &rct);
nWidth = nScreenWidth - rct.left;

if((nWidth < nMenuWidth)/* && (m_fRedrawMenu)*/)
{
bRet = ::MoveWindow((HWND)hWndMenu,
rct.right,
rct.bottom,
nMenuWidth,
nMenuHeight,
false
);

//bRet = ::SetWindowPos((HWND)hWndMenu, NULL, rct.right, rct.bottom, 0, 0, SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
}
break;
}

Thanks ,
Kansana

ovidiucucu
April 27th, 2007, 04:57 AM
I'm not sure if the corresponding window of class "#32768" is already created or not when WM_INITMENUPOPUP is sent, but for sure it becomes visible and is moved by the system after that.

So, one solution is to post an user message from within WM_INITMENUPOPUP message handler.

Here is a Win32 dialog-based example showing how to achieve your needs:

#include <windows.h>
#include <windowsx.h>
#include "resource.h"

#define WM_APP_INITMENUPOPUP (WM_APP+1)
BOOL CALLBACK MyDialogProc(HWND, UINT, WPARAM, LPARAM);
void OnInitMenuPopup(HWND, HMENU, UINT, BOOL);
void OnContextMenu(HWND, HWND, UINT, UINT);
void OnAppInitMenuPopup();
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1),
NULL, MyDialogProc);
return 0;
}

BOOL CALLBACK MyDialogProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
BOOL bRet = FALSE; // not handled
switch(uMsg)
{
HANDLE_MSG(hWndDlg, WM_INITMENUPOPUP, OnInitMenuPopup);
HANDLE_MSG(hWndDlg, WM_CONTEXTMENU, OnContextMenu);
case WM_APP_INITMENUPOPUP:
OnAppInitMenuPopup(); bRet = TRUE; // handled
break;
case WM_COMMAND:
switch(wParam)
{
case IDCANCEL:
EndDialog(hWndDlg, IDCANCEL); bRet = TRUE; // handled
break;
}
default:
break;
}
return bRet;
}
void OnContextMenu(HWND hWndDlg, HWND hWndContext, UINT xPos, UINT yPos)
{
HMENU hMenu = GetMenu(hWndDlg);
HMENU hSubMenu = GetSubMenu(hMenu, 0);
TrackPopupMenu(hSubMenu, TPM_LEFTALIGN, xPos, yPos, 0, hWndDlg, NULL);
}
void OnInitMenuPopup(HWND hWndDlg, HMENU hMenu, UINT item, BOOL fSystemMenu)
{
PostMessage(hWndDlg, WM_APP_INITMENUPOPUP, 0, 0);
}
void OnAppInitMenuPopup()
{
HWND hWndMenu = FindWindowA("#32768", NULL);
RECT rcMenu = {0};
GetWindowRect(hWndMenu, &rcMenu);
// Next, calculate and move it to the desired position...
}

NOTE: When posting source code, please use CODE TAGS (http://www.codeguru.com/forum/misc.php?do=bbcode#code)!
Thanks!

Kansana
April 27th, 2007, 08:59 AM
Thanks a lot ovidiucucu.It was working as expected

//JP added flex table