救命:请问用菜单扩展模板动态创建菜单为什么无法加载到窗口?
各位大虾,
请问用菜单扩展模板动态创建菜单为什么无法加载到窗口?下面是我写的所有的代码
其中把
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;
}
谢谢