2003-04-03 [長年日記]

HMENUからSHCreateMenuBar

Pocket PCではSHCreateMenuBarでメニューを作りますが、リソースから作ることしか出来ません(Pocket PC 2002では、フラグを指定すればHMENUから作成できるようです)。そこで、自前で作る方法を。まず、リソースに以下を追加します。

IDR_EMPTY RCDATA DISCARDABLE PURE
BEGIN
    IDR_EMPTY, 0,
END

IDR_EMPTYは適当に定義しておきます。そして、このリソースで空のメニューを作ってから、TB_INSERTBUTTONでメニューを追加していきます。ここで面倒くさがって、SHCMBF_EMPTYBARを指定して空のメニューを作ると、以降の追加も出来なくなってしまうようなので注意です。

HINSTANCE hInst = ...; // リソースが含まれているEXE/DLLのハンドル
HWND hwnd = ...;       // フレームウィンドウのハンドル
HMENU hmenu = ...;     // このメニューハンドルから作る
 
SHMENUBARINFO mbi = {
  sizeof(mbi),
  hwnd,
  0,
  IDR_EMPTY,
  hInst,
  0,
  0
};
::SHCreateMenuBar(&mbi);
HWND hwndMenu = mbi.hwndMB;
 
int nId = 1000;
TCHAR tszText[256];
for (int n = 0; ; ++n) {
  MENUITEMINFO mii = {
    sizeof(mii),
    MIIM_TYPE | MIIM_SUBMENU,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    tszText,
    sizeof(tszText)/sizeof(tszText[0]) - 1,
  };
  if (!::GetMenuItemInfo(hmenu, n, TRUE, &mii))
    break;
   
#define TBSTYLE_NO_DROPDOWN_ARROW 0x0080
  TBBUTTON button = {
    I_IMAGENONE,
    nId++,
    TBSTATE_ENABLED,
    TBSTYLE_DROPDOWN | TBSTYLE_NO_DROPDOWN_ARROW | TBSTYLE_AUTOSIZE,
    { 0, 0 },
    reinterpret_cast(mii.hSubMenu),
    reinterpret_cast(tszText)
  };
  ::SendMessage(hwndMenu, TB_INSERTBUTTON, n,
    reinterpret_cast(&button));
}

エラー処理は省いてあります。

Pocket PCのIMLangConvertCharset::DoConversionFromUnicode

IMLangConvertCharset::DoConversionFromUnicodeやDoConversionToUnicodeをするときには必要なバッファのサイズを知るために、

IMLangConvertCharset* pCharset = ...;
WCHAR* p = ...;
UINT nLen = ...;
UINT nDstLen = 0;
pCharset->DoConversionFromUnicode(p, &nLen, 0, &nDstLen);

のようにまず呼び出すのですが、Pocket PCのMLangだとこのときにnLenの値が0に書き換わってしまうようです。他のプラットフォームではならなかった(同じWindows CE 3.00系のHPC2000でもならなかった)のですが、Pocket PCの実装だけ別なんでしょうか。処理した長さがセットされるという観点からすれば、Pocket PCの動作が正しい気もしますが。。

ついでに、nLenに0をセットして呼び出すとE_FAILになってしまう模様です。S_OKでいい気がするんですけどね。


トップ «前の日記(2003-04-02) 最新 次の日記(2003-04-04)»