救命:请问用菜单扩展模板动态创建菜单为什么无法加载到窗口?

lifengliu2000 2005-10-20 10:36:03
各位大虾,
请问用菜单扩展模板动态创建菜单为什么无法加载到窗口?下面是我写的所有的代码
其中把
HWND myHwnd = CreateWindow("MyBvMenu","JIANG",WS_OVERLAPPEDWINDOW,0,0,300,200,NULL,LoadMenuResFormFile(),hInstance,NULL);
改成
HWND myHwnd = CreateWindow
("MyBvMenu","JIANG",WS_OVERLAPPEDWINDOW,0,0,300,200,NULL, 0,
hInstance,NULL);
就可以了。请问这是什么原因阿?

下面是我写的所有的代码

// testBvMenu.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#define MAXMENUITEM 4

typedef struct
{
WORD wVersion;
WORD wOffset;
DWORD dwHelpId;
} MENUEX_TEMPLATE_HEADER;

#pragma pack(4)
typedef struct
{
DWORD dwType;
DWORD dwState;
DWORD menuId;
WORD bResInfo;
//
//WCHAR[] szText; //these are variable, so
//DWORD dwHelpId; //in D, these must be seperate from struct;

} MENUEX_TEMPLATE_ITEM;

#pragma pack()

enum // values for MenuExTemplateItem.bResInfo
{
RI_NORM = 0x00,
RI_SUBM = 0x01,
RI_ENDM = 0x80
};

enum // identifiers for menu ids
{
IDM_FILE = 40001,
IDM_FILE_OPEN = 40002,
IDM_FILE_SAVE = 40003,
IDM_FILE_CLOSE = 40004
//... There's a lot more
};

//根据4字节对齐方式,计算caption实际占用空间
int CountStrLen(const char *str)
{
int nLen = strlen(str);
if(nLen % 4)
{
nLen += 4 - nLen % 4;
}

return nLen;
}

WCHAR* Char2Wchar(const char *str)
{
int nLen = strlen(str);
WCHAR* wstr = new WCHAR[nLen];
MultiByteToWideChar(CP_ACP, 0, str, -1, wstr, nLen);
return wstr;
}

INT m_nOffset = 0;
void addItem(MENUEX_TEMPLATE_ITEM *pItem, DWORD dwType, DWORD dwState, UINT uId, WORD bResInfo, WCHAR * text, DWORD helpId)
{

pItem->dwType = dwType;
pItem->dwState = dwState;
pItem->menuId = uId;
pItem->bResInfo = bResInfo;

/*************************************************************************
1) szText is a variable length string, possibly omitted (if the particular menu
item is a seperator.
2) dwHelpId is only included (on a DWORD (4 byte) boundary) if the menu item
opens a submenu.
/************************************************************************/
if(dwState == MFT_SEPARATOR)
{
m_nOffset += sizeof(MENUEX_TEMPLATE_ITEM);
return;
}

int nLen = wcslen(text);

//judge whether it has caption property.
if (nLen > 0)
{
memcpy(pItem + sizeof(MENUEX_TEMPLATE_ITEM),text,nLen);
}
else
{
m_nOffset += sizeof(MENUEX_TEMPLATE_ITEM);
return;
}

//align 4 bytes
if(nLen % 4 != 0)
{
nLen = nLen + 4 - nLen % 4;
}

if (bResInfo == RI_SUBM)
{
memcpy(pItem + sizeof(MENUEX_TEMPLATE_ITEM) + nLen,&helpId,sizeof(DWORD));
m_nOffset += sizeof(MENUEX_TEMPLATE_ITEM) + nLen + sizeof(DWORD);
return;
}

m_nOffset += sizeof(MENUEX_TEMPLATE_ITEM) + nLen;

delete []text;
text = NULL;
}
HMENU LoadMenuResFormFile()
{
//Open ini File to get useful info

int nCount = CountStrLen("&File") + CountStrLen("&OPEN") + CountStrLen("&SAVE") + CountStrLen("&Exit") ;
LPVOID lpMem;
MENUEX_TEMPLATE_HEADER *pHheader;
MENUEX_TEMPLATE_ITEM *pItem;
lpMem = ::HeapAlloc(::GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(MENUEX_TEMPLATE_HEADER)+MAXMENUITEM *sizeof(MENUEX_TEMPLATE_ITEM ) + nCount + 12);

pHheader = (MENUEX_TEMPLATE_HEADER *)lpMem;
pHheader->wVersion = 1;
pHheader->wOffset = 4;
pHheader->dwHelpId = 0;

//adjust the offset of memory
m_nOffset += sizeof(MENUEX_TEMPLATE_HEADER);

pItem = (MENUEX_TEMPLATE_ITEM *)lpMem;

addItem(pItem,MFT_STRING, MFS_ENABLED, IDM_FILE, RI_SUBM, Char2Wchar("&File"), 1);
addItem(pItem + m_nOffset,MFT_STRING, MFS_ENABLED, IDM_FILE_OPEN, RI_NORM, Char2Wchar("&OPEN"), 2);
addItem(pItem + m_nOffset,MFT_STRING, MFS_ENABLED, IDM_FILE_SAVE, RI_NORM, Char2Wchar("&SAVE"), 3);
addItem(pItem + m_nOffset,MFT_STRING, MFS_ENABLED,IDM_FILE_CLOSE, RI_ENDM, Char2Wchar("&Exit"), 4);

HMENU hMenuEx = ::LoadMenuIndirect(lpMem) ;

return hMenuEx;
}

LRESULT CALLBACK wndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{

case WM_CLOSE:
DestroyWindow(hWnd);
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);

}


int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
WNDCLASS wnd;
wnd.hInstance = hInstance;
wnd.lpfnWndProc = wndProc;
wnd.lpszClassName = "MyBvMenu";
wnd.cbClsExtra = 0;
wnd.cbWndExtra = 0;
wnd.hCursor = NULL;
wnd.hbrBackground = ::CreateSolidBrush(RGB(0,0,0));
wnd.hIcon = NULL;
wnd.lpszMenuName = NULL;
wnd.style = CS_VREDRAW|CS_HREDRAW;
::RegisterClass(&wnd);

///////////////////////////////////////////////////////////////////////////
// 就是这一句
HWND myHwnd = CreateWindow("MyBvMenu","JIANG",WS_OVERLAPPEDWINDOW,0,0,300,200,NULL,LoadMenuResFormFile(),hInstance,NULL);

::ShowWindow(myHwnd,SW_SHOW);
::UpdateWindow(myHwnd);

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

::UnregisterClass("MyBvMenu",hInstance);
return 0;
}

谢谢
...全文
101 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
lifengliu2000 2005-11-01
  • 打赏
  • 举报
回复
up
菜牛 2005-10-21
  • 打赏
  • 举报
回复
你理解我说的么?
lifengliu2000 2005-10-21
  • 打赏
  • 举报
回复
救命啊
lifengliu2000 2005-10-21
  • 打赏
  • 举报
回复
谢谢 Mackz(在相互), 您说得对,我改过来了!但是还有点儿别的问题,还是挂不上啊!
菜牛 2005-10-20
  • 打赏
  • 举报
回复
太复杂了,感觉你把简单事情复杂化了。

m_nOffset的作用被你误解了。比如这句:
m_nOffset += sizeof(MENUEX_TEMPLATE_ITEM);
你认为m_nOffset是以字节为单位的,而这句
pItem + m_nOffset
实际上是以MENUEX_TEMPLATE_ITEM为单位的,结果如何不得而知。
yayaniuniu502 2005-10-20
  • 打赏
  • 举报
回复
看看帮助吧,null不行的

hMenu
[in] Handle to a menu, or specifies a child-window identifier depending on the window style. For an overlapped or pop-up window, hMenu identifies the menu to be used with the window; it can be NULL if the class menu is to be used. For a child window, hMenu specifies the child-window identifier, an integer value used by a dialog box control to notify its parent about events. The application determines the child-window identifier; it must be unique for all child windows with the same parent window.
teli_eurydice 2005-10-20
  • 打赏
  • 举报
回复
帮你up
lifengliu2000 2005-10-20
  • 打赏
  • 举报
回复
救命啊
nkwesley 2005-10-20
  • 打赏
  • 举报
回复
太长了,帮你UP吧

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧