017:WindowsMobile特有のウィンドウ作成

WindowsMobile特有のウィンドウ作成

今まで、通常のWindowsと同じようにメインウィンドウを作成してきました。単純にウィンドウを表示すると、下のメニューバーの部分が切れているのがわかると思います。
そこでSIP(Software Input Panel)の高さを考慮したウィンドウサイズを作成し、メニューバーを作成したいと思います。

SIPを考慮したウィンドウサイズの設定

SIPの情報を得るにはSHSipInfo関数を使用します。SIP領域を除いた有効なウィンドウサイズを取得し、MoveWindow関数でウィンドウサイズを変更しています。

SHSipInfo関数  SIPの状態を取得・設定します。

BOOL WINAPI SHSipInfo(
  UINT uiAction,
  UINT uiParam,
  PVOID pvParam,
  UINT fWinIni
);

MoveWindow関数  指定されたウィンドウの位置とサイズを変更します。

BOOL MoveWindow(
  HWND
hWnd,      // ウィンドウのハンドル
  int X,          // 横方向の位置
  int Y,          // 縦方向の位置
  int nWidth,     // 幅
  int nHeight,    // 高さ
  BOOL bRepaint   // 再描画オプション
);

SHSipInfo関数はaygshell.hに含まれています。

#include <aygshell.h>

これだけだとビルド時にエラーとなってしまいます。そこで必要であればaygshell.libをリンクするようにリンカに指示を行います。

#pragma comment( lib, "aygshell.lib" )

SHSipInfo関数のほかに、SipGetInfo関数を使用することで同じようにSIPの情報を得ることが出来ますが、今回は使用しません。

BOOL SipGetInfo(
  SIPINFO* pSipInfo
);

SIPの状態が変化したときは、トップレベルウィンドウに対してWM_SETTINGCHANGEイベントが通知され、ウィンドウプロシージャの第3引数 WPARAM に、SPI_SETSIPINFOがセットされます。
このイベントが通知されたら、ShShipInfo関数でSIP領域を除いた有効なウィンドウサイズを取得し、MoveWindow関数でウィンドウサイズを変更しています。

       case WM_SETTINGCHANGE:
           switch( wp
)
           
{
               case SPI_SETSIPINFO
:
                   memset( &si, 0, sizeof( si ) );
                   si.cbSize = sizeof( si
);
                   if( SHSipInfo( SPI_GETSIPINFO, 0, &si, 0 )
)
                   
{
                       MoveWindow
(
                           hWnd,
                           si.rcVisibleDesktop.left,
                           si.rcVisibleDesktop.top,
                           si.rcVisibleDesktop.right

                           si.rcVisibleDesktop.left,
                           si.rcVisibleDesktop.bottom

                           si.rcVisibleDesktop.top,
                           TRUE
);
                   
}
                   break
;
           
}
           break
;

メニューバーの作成

次にメニューバーを作成します。作成にはSHCreateMenuBar関数を使用します。

BOOL SHCreateMenuBar(
  SHMENUBARINFO * pmb
);

SHMENUBARINFO構造体に、メニューの情報を格納してSHCreateMenuBar関数に渡します。サンプルの例ではSHCMBF_EMPTYBARを指定することで、空のメニューバーを作成しています。

 SHMENUBARINFO smi = {sizeof(SHMENUBARINFO),hWnd,SHCMBF_EMPTYBAR};
 SHCreateMenuBar(&smi);

メニューの作成については、また別の機会に説明しますが、ここでは単純に見た目を整えるための空のメニューを作成して表示しています。
では、ソースファイルです。

 

// SampleWindow001.cpp

#include <aygshell.h>
#pragma comment( lib, "aygshell.lib" )  // 必要であれば aygshell.lib をリンクするよう、リンカに指示をする。

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
ATOM InitApp(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);

WCHAR szClassName[] = L"SampleWindow001"; // ウィンドウクラス。UNICODEとしての文字列定数

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine,int nShowCmd)
{
   MSG msg;
   BOOL bRet;

   if (!InitApp(hInstance))
       return FALSE;
   if (!InitInstance(hInstance,nShowCmd))
       return FALSE;
   while((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) {
       if (bRet == -1){
           break;
       } else {
           TranslateMessage(&msg);
           DispatchMessage(&msg);
       }
   }
   return (int)msg.wParam;
}

// ウィンドウクラスの登録

ATOM InitApp(HINSTANCE hInst)
{
   WNDCLASSW wc;
   wc.style        = CS_HREDRAW|CS_VREDRAW;
   wc.lpfnWndProc  = WndProc;  // プロシージャ名
   wc.cbClsExtra   = 0;
   wc.cbWndExtra   = 0;
   wc.hInstance    = hInst;
   wc.hIcon        = NULL;     // 未サポート
   wc.hCursor      = NULL;     // 未サポート
   wc.hbrBackground= (HBRUSH) COLOR_WINDOW;
   wc.lpszMenuName = NULL;     // 未サポート
   wc.lpszClassName=(LPCWSTR) szClassName;

   return (RegisterClassW(&wc));
}

// ウィンドウの生成
BOOL InitInstance(HINSTANCE hInst, int nShowCmd)
{
   HWND hWnd;

   hWnd = CreateWindowW(szClassName,L"SampleWindow",
       WS_CLIPCHILDREN,    // ウィンドウの種類
       CW_USEDEFAULT,      // x座標
       CW_USEDEFAULT,      // y座標
       CW_USEDEFAULT,      // 幅
       CW_USEDEFAULT,      // 高さ
       NULL,               // 親ウィンドウのハンドル。親を作るのでNULL
       NULL,               // メニューハンドルまたは子ウィンドウID
       hInst,              // インスタンスハンドル
       NULL);
   if (!hWnd)
       return FALSE;
   ShowWindow(hWnd, nShowCmd);
   UpdateWindow(hWnd);
   return TRUE;
}

// ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
   SIPINFO si;
   SHMENUBARINFO smi = {sizeof(SHMENUBARINFO),hWnd,SHCMBF_EMPTYBAR};// 空のメニューバー
   switch (msg){
       case WM_CR
EATE:
           // メニューバーを作成する。
           SHCreateMenuBar(&smi);
           break;
       case WM_SETTINGCHANGE:
           switch( wp )
           {
               case SPI_SETSIPINFO:
                   // SIP領域を除いた有効なウィンドウサイズを取得し、
                   
// MoveWindow関数でウィンドウサイズを変更する。
                   memset( &si, 0, sizeof( si ) );
                   si.cbSize = sizeof( si
);
                   if( SHSipInfo( SPI_GETSIPINFO, 0, &si, 0 ) )
                   {
                       MoveWindow(
                           hWnd,
                           si.rcVisibleDesktop.left,
                           si.rcVisibleDesktop.top,
                           si.rcVisibleDesktop.right
-
                           si.rcVisibleDesktop.left,
                           si.rcVisibleDesktop.bottom
-
                           si.rcVisibleDesktop.top,
                           TRUE
);
                   }
                   break;
           }
           break;

       case WM_DESTROY:
           PostQuitMessage(0);
           break;
       default:
           return (DefWindowProc(hWnd, msg, wp, lp));
   }
   return 0;
}

 

今日はここまでです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です