www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Menu "Templates" for Windows

I'm still working a my first Windows app in D, so I'd like a litte guidance to
see if I'm doing this right.

Here's the C definitions of the templates:
typedef struct {
WORD wVersion;
WORD wOffset;
DWORD dwHelpId;
} MENUEX_TEMPLATE_HEADER;

typedef struct {
DWORD dwType;
DWORD dwState;
DWORD menuId;
WORD bResInfo;
WCHAR szText;
DWORD dwHelpId;
} MENUEX_TEMPLATE_ITEM;

What I've devised is creating a ubyte[], and ~= each piece to it, one at a time.
Doing this, the header is easy, but the item isn't.
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.

With that in mind, here's my idea in code (I'm using the Core32 files):


struct MenuExTemplateHeader
{
WORD    wVersion;
WORD    wOffset;
DWORD   dwHelpId;
}

struct MenuExTemplateItem
{
align(4)
{
DWORD    dwType;
DWORD    dwState;
UINT     uId;
WORD     bResInfo;
}
//WCHAR[]  szText;     //these are variable, so
//DWORD    dwHelpId;   //in D, these must be seperate from struct;
}

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
//... There's a lot more
}

ubyte *assembleMenu()
{
wchar[] text;
DWORD   helpId;
ubyte*  temp;       //work pointer
ubyte[] outArray;

MenuExTemplateHeader header;
MenuExTemplateItem   item;     //reused for each menu item

//first, the header:
header.wVersion = 1;
header.wOffset  = 4;
header.dwHelpId = 0;
temp = cast(ubyte *)&header;
outArray[] ~= temp[0 .. header.sizeof];

void addItem(DWORD dwType, DWORD dwState, uint uId, WORD bResInfo, wchar text,
DWORD helpId)
{
item.dwType   = dwType;
item.dwState  = dwState;
item.uId      = uId;
item.bResInfo = bResInfo;
temp = cast(ubyte *)&item;
outArray[] ~= temp[0 .. item.sizeof];

if (text.length > 0);
{
test ~= "\0";
temp = cast (ubyte *)&text;
outArray ~= temp[0 .. text.sizeof];
}

if (outArray.length % 4 != 0)               // make sure array is DWORD aligned
outArray.length = outArray.length + (4 - outArray.length % 4);  // works since
outArray is in ubytes
if (bResInfo == RI_SUBM)
{
temp = cast (ubyte *)&helpId;
outArray ~= temp[0 .. helpId.sizeof];
}
}

// File
addItem(MFT_STRING, MFS_ENABLED, IDM_FILE, RI_SUMB, "&File", 1);


return outArray;

}
Aug 14 2004