SetWindowLong関数


LONG SetWindowLong(
 HWND hWnd,
 int nIndex,
 LONG dwNewLong
);

指定されたウィンドウの属性を変更します。
拡張ウィンドウメモリのデータも書き換えることができます。

hWndウィンドウのハンドルを指定します。
nIndexウィンドウに関するデータのうち、どのデータを書き換えるのかを指定します。
GWL_EXSTYLE拡張ウィンドウスタイルを書き換えます。
GWL_STYLEウィンドウスタイルを書き換えます。
GWL_WNDPROCウィンドウプロシージャのアドレスを書き換えます。
GWL_HINSTANCEアプリケーションのインスタンスハンドルを書き換えます。
GWL_IDウィンドウのIDを書き換えます。
dwNewLong新しく設定する値を32ビット値で指定します。
Windows > ウィンドウの作成 | comments (0) | trackbacks (0)

SetWindowPos関数


BOOL SetWindowPos(
 HWND hWnd,
 HWND hWndInsertAfter,
 int X,
 int Y,
 int cx,
 int cy,
 UINT uFlags
);

子ウィンドウ、ポップアップウィンドウ、トップレベルウィンドウにおいて、
そのサイズ、位置、Zオーダーを変更します。

hWndウィンドウのハンドルを指定します。
hWndInsertAfterhWndパラメータで指定したウィンドウに先行するウィンドウのハンドルを指定します。
HWND_BOTTOMウィンドウをZオーダーの最後(一番下)に置きます。
HWND_NOTOPMOSTウィンドウを最前面ウィンドウ(WS_EX_TOPMOST)以外のすべてのウィンドウの上位に置きます。
HWND_TOPウィンドウをZオーダーの最初(一番上)に置きます。
HWND_TOPMOSTウィンドウを最前面ウィンドウにします。
Xウィンドウの左上隅の新しいx座標を指定します。
Yウィンドウの左上隅の新しいy座標を指定します。
cxウィンドウの新しい幅をピクセル単位で指定します。
cyウィンドウの新しい高さをピクセル単位で指定します。
uFlagsウィンドウのサイズおよび位置の変更に関するフラグを指定します。
SWP_HIDEWINDOWウィンドウを非表示にします。
SWP_NOACTIVATEウィンドウをアクティブにしません。
SWP_NOMOVE現在の位置を維持します。(X,Yを無視します。)
SWP_NOOWNERZORDERオーナー・ウィンドウのZオーダーを変えません。
SWP_NOREDRAWウィンドウを再描画しない
SWP_NOSIZE現在のサイズを維持します。(cx,cyを無視します。)
SWP_NOZORDER現在のZオーダーを維持します。(hWndInsertAfterを無視します。)
SWP_SHOWWINDOWウィンドウを表示します。
Windows > ウィンドウの作成 | comments (0) | trackbacks (0)

汎用ポインタ

void *変数名


#include <stdio.h>

typedef struct tagTest {
 char c;
 int i;
} _TEST;

void Disp( void *t )
{
 printf( "%d\n", sizeof( *(_TEST*)t ) );
}

void main()
{
 _TEST test;
 Disp( &test );
}


汎用ポインタは任意のポインタを代入する事が可能であり、
同様に型キャストによって型を復元させる事ができます。


#include <stdio.h>

void Disp( void *t )
{
 char *pstr = (char*)t;
 puts( pstr );
 putchar( (int)*pstr );

 int *pd = (int*)t;
 putchar( *pd );
}

void main()
{
 char *str = "abcdefg";
 Disp( str );
}


あらゆる型のポインタをキャストできます。
C > ポインタ | comments (0) | trackbacks (0)

CreateThread()関数


HANDLE CreateThread(
 LPSECURITY_ATTRIBUTES lpsa,
 DWORD dwStackSize,
 LPTHREAD_START_ROUTINE pfnThreadProc,
 void* pvParam,
 DWORD dwCreationFlags,
 DWORD* pdwThreadId
);

新規作成したスレッドへのハンドルを返します。
失敗した場合は NULL を返します。
スレッドは、呼び出し側プロセスのアドレス空間で実行されます。

lpsa新しいスレッドのセキュリティ属性。
取得したハンドルの子プロセスへの継承を許可するかどうかを決める、SECURITY_ATTRIBUTES構造体へのポインタを指定します。
NULLを指定すると、ハンドルは継承されません。
※特別な意図が無い限りNULLでいいでしょう。
dwStackSize新しいスレッドのスタックサイズ。
新しいスレッドが持つスタックのサイズを、バイト単位で指定します。
利用可能なメモリのサイズよりも大きなサイズを指定すると、CreateThread関数は失敗します。
0を指定すると、デフォルトのサイズになります。
※Windowsは必要に応じてスタックサイズを拡張するため、デフォルトサイズを表す0を指定します。
pfnThreadProc新しいスレッドのスレッドプロシージャ。
新しいスレッドの開始アドレスを指定します。
通常、WINAPI呼び出し規約で定義された関数のアドレスを指定します。
この関数の書式を次に示します。
DWORD WINAPI ThreadFunc( LPVOID );
pvParamスレッドプロシージャに渡されるパラメータ。
通常はポインタとして使います。
この引数を利用して何らかのデータを渡せば、スレッドごとに異なる処理をさせることができます。
受け渡すデータが多い場合は構造体にデータを格納し、そのポインタを渡します。
dwCreationFlags作成フラグ(0またはCREATE_SUSPENDED)。
CREATE_SUSPENDEDを指定するとスレッドを中断された状態で作成され、ResumeThread関数を呼び出すまでは動作しません。
※通常は0を指定して、作成と同時にスレッドを起動します。
pdwThreadId正常終了したときに、新しく作成されたスレッドのスレッドIDを受け取るDWORD型変数へのアドレス。


CreateThread( NULL, 0, ThreadFunc, ( LPVOID )&param, 0, &dwThreadID );


・呼び出し側は、作成に成功したスレッドの関数の終了を待ちません。
・作成されたスレッドは、関数の終了をもって破棄されます。
・マルチスレッドは、複数のコードがばらばらのタイミングで動作するため、
複数のスレッドが同じグローバル変数を参照する場合などは、
プログラムの方法によってはデータの整合性が失われるなどの
問題が発生する事もあります。
・C言語のライブラリを利用する場合はCreateThread関数ではなく_beginthread()関数を使うようにします。
Windows > スレッド | comments (0) | trackbacks (0)

PeekMessage()関数


BOOL PeekMessage(
 LPMSG lpMsg,
 HWND hWnd,
 UINT wMsgFilterMin,
 UINT wMsgFilterMax,
 UINT wRemoveMsg
);


lpMsgメッセージを取得するMSG構造体へのポインタ
hWndメッセージを取得するウィンドウへのハンドル
wMsgFilterMin取得するメッセージの最小値。両方0にするとフィルタリングしない。
wMsgFilterMax取得するメッセージの最大値。両方0にするとフィルタリングしない。
wRemoveMsgPM_REMOVE メッセージをキューから削除する
PM_NOREMOVE メッセージをキューから削除しない。

メッセージを取得した時は、0以外の値が返ります。
メッセージを取得しなかった時は、0が返ります。

GetMessage関数と違い、PeekMessage関数は、キュー内にメッセージが置かれるまで待つことはありません。


while (1) {
 if ( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) ) {
  // メッセージがある場合はそれを処理する
  if ( msg.message == WM_QUIT ) break;
  DispatchMessage( &msg );
 } else {
  // アイドル時の処理を行う
 }
}

Windows > メッセージループ | comments (0) | trackbacks (0)

子ウィンドウの作成1


#include <windows.h>
#define CLASSNAME "MyWindowClass"

// グローバル変数:
HINSTANCE hInst;
// このコード モジュールに含まれる関数の宣言を転送します:
ATOM MyRegisterClass( HINSTANCE );
BOOL InitInstance( HINSTANCE, int );
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM );
//----------------------------------------------------------------
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
 MSG msg;

 MyRegisterClass( hInstance );
 if ( !InitInstance( hInstance, nCmdShow ) ) return FALSE;

 // メイン メッセージ ループ:
 while ( GetMessage( &msg, NULL, 0, 0 ) ) {
  TranslateMessage( &msg );
  DispatchMessage( &msg );
 }

 return ( int )msg.wParam;
}
//----------------------------------------------------------------
ATOM MyRegisterClass( HINSTANCE hInstance ) {(省略)}
//----------------------------------------------------------------
BOOL InitInstance( HINSTANCE hInstance, int nCmdShow )
{
 HWND hWnd, hWndChild, hWndOwned;

 hInst = hInstance;

 // メインウィンドウ
 hWnd = CreateWindow( CLASSNAME, "Main Window",
  WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
  300, 200, NULL, NULL, hInstance, NULL );
 if ( !hWnd ) return FALSE;

 // 子ウィンドウ
 hWndChild = CreateWindow( CLASSNAME, "Child Window",
  WS_CHILD | WS_CAPTION | WS_VISIBLE,
  0, 0, 150, 100, hWnd, NULL, hInstance, NULL );
 if ( !hWndChild ) return FALSE;

 // 被所有ウィンドウ
 hWndOwned = CreateWindow( CLASSNAME, "Owned Window",
  WS_POPUP | WS_CAPTION | WS_VISIBLE,
  0, 0, 150, 100, hWnd, NULL, hInstance, NULL );
 if ( !hWndOwned ) return FALSE;

 // ウィンドウを表示する
 ShowWindow( hWnd, nCmdShow );
 UpdateWindow( hWnd );

 return TRUE;
}
//----------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) {(省略)}


<親子関係>
ウィンドウ・スタイルにWS_CHILDを指定して、hWndParentに親ウィンドウのハンドルを指定する。
・子ウィンドウは親ウィンドウのクライアント領域の外側に表示したり移動することができない。
・親ウィンドウを移動すると子ウィンドウも一緒に移動する。
・親ウィンドウを最小化すると子ウィンドウも見えなくなる。
・自由に親ウィンドウを変更することができる。

<所有/被所有>
ウィンドウ・スタイルにWS_CHILDを指定せず、hWndParentにオーナー・ウィンドウのハンドルを指定する。
・被所有ウィンドウの移動や表示が、所有ウィンドウの内部に限定されない。
・所有ウィンドウを移動しても被所有ウィンドウは移動しない。
・所有ウィンドウを最小化すると被所有ウィンドウも見えなくなる。
・オーナー・ウィンドウはいったん設定すると、後から変更できない。

071210.jpg
Windows > ウィンドウの作成 | comments (0) | trackbacks (0)

子ウィンドウの作成2

アプリケーションのウィンドウの内部に配置するボタンなどのGUI部品も、
通常は子ウィンドウの形で作ります。


LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
 PAINTSTRUCT ps;
 HDC hdc;
 char str[256];

 static HWND hwButton0, hwButton1;
 static int iMode =0;

 switch (message) {
 case WM_CREATE:
  hwButton0 = CreateWindow( "Button", "Button0", WS_CHILD | WS_VISIBLE, 16, 8, 80, 24, hWnd, ( HMENU )0, hInst, NULL);
  hwButton1 = CreateWindow( "Button", "Button1", WS_CHILD | WS_VISIBLE, 108, 8, 80, 24, hWnd, ( HMENU )1, hInst, NULL);
  break;
 case WM_COMMAND:
  switch ( LOWORD( wParam ) ) { // クリックされたボタン判別
  case 0: // hwButton0
   iMode = 0;
   InvalidateRect( hWnd, NULL, TRUE );
   break;
  case 1: // hwButton1
   iMode = 1;
   InvalidateRect( hWnd, NULL, TRUE );
   break;
  }
  break;
 case WM_PAINT:
  hdc = BeginPaint(hWnd, &ps);
  // TODO: 描画コードをここに追加してください...
  wsprintf( str, "押されたボタンは%d", iMode );
  TextOut( hdc, 16, 40, str, ( int )strlen( str ) );
  EndPaint(hWnd, &ps);
  break;
 case WM_DESTROY:
  PostQuitMessage(0);
  break;
 default:
  return DefWindowProc( hWnd, message, wParam, lParam );
 }
 return 0;
}


ButtonなどWindowsに用意されているGUI部品のウィンドウを作る際には
Windowsにあらかじめ用意されているウィンドウクラスを使います。

追加されたボタンはWM_COMMANDメッセージを送ってきます。
hMenuの値がwParamの下位ワードに入っているので、
この値からクリックされたボタンを特定できます。

070403.jpg
Windows > ウィンドウの作成 | comments (0) | trackbacks (0)

CreateWindowEx関数


HWND CreateWindowEx(
 DWORD dwExStyle,
 LPCTSTR lpClassName,
 LPCTSTR lpWindowName,
 DWORD dwStyle,
 int x,
 int y,
 int nWidth,
 int nHeight,
 HWND hWndParent,
 HMENU hMenu,
 HINSTANCE hInstance,
 LPVOID lpParam
);

拡張ウィンドウ・スタイルを指定して、ウィンドウを作成する為には、CreateWindowの代わりに、その機能拡張版であるCreateWindowExを利用する。
CreateWindowExのプロトタイプは、先頭に拡張ウィンドウ・スタイルを指定するdwExStyleが追加されている点を除けばCreateWindowと同じである。

WS_EX_ACCEPTFILESこのスタイルで作成されたウィンドウでは、ファイルをドラッグ アンド ドロップできます。
WS_EX_APPWINDOW一番上にあるウィンドウを表示するときに、強制的にタスクバーに含みます。
WS_EX_CLIENTEDGEウィンドウを 3 次元で表示することを指定します。つまり、ウィンドウには、くぼんだ境界線が付きます。
WS_EX_CONTEXTHELPウィンドウのタイトル バーに疑問符 (?) を追加します。ユーザーが疑問符 (?) をクリックすると、カーソルがポインタの付いた疑問符 (?) に変わります。続いてユーザーが子ウィンドウをクリックすると、その子ウィンドウが WM_HELP メッセージを受け取ります。
WS_EX_CONTROLPARENTユーザーが、Tab キーを使ってウィンドウ内の子ウィンドウ間を移動できるようにします。
WS_EX_DLGMODALFRAME二重の境界を持つウィンドウを指定します。パラメータ dwStyle に WS_CAPTION スタイル フラグを指定することにより、タイトル バーを追加することもできます。
WS_EX_LEFTウィンドウに汎用左揃えプロパティを指定します。これは、既定の設定です。
WS_EX_LEFTSCROLLBARクライアント領域の左に垂直スクロール バーを配置します。
WS_EX_LTRREADING左から右への読み取り順序でウィンドウのテキストを表示します。これは、既定の設定です。
WS_EX_MDICHILDMDI 子ウィンドウを作成します。
WS_EX_NOPARENTNOTIFYこのスタイルを指定されている子ウィンドウは、作成または破棄されるときに親ウィンドウに WM_PARENTNOTIFY メッセージを送りません。
WS_EX_OVERLAPPEDWINDOWWS_EX_CLIENTEDGE スタイルと WS_EX_WINDOWEDGE スタイルを組み合わせます。
WS_EX_PALETTEWINDOWWS_EX_WINDOWEDGE スタイルと WS_EX_TOPMOST スタイルを組み合わせます。
WS_EX_RIGHTウィンドウに汎用右揃えプロパティを指定します。このスタイルは、ウィンドウ クラスに依存します。
WS_EX_RIGHTSCROLLBARクライアント領域の右に垂直スクロール バー (存在する場合) を配置します。これは、既定の設定です。
WS_EX_RTLREADING右から左への読み取り順序でウィンドウのテキストを表示します。
WS_EX_STATICEDGE3 次元の境界線スタイルを持つウィンドウを作成します。このウィンドウは、ユーザーの入力を受け付けない項目用に使用します。
WS_EX_TOOLWINDOWツール ウィンドウを作成します。このウィンドウは、フローティング ツール バーとして使用します。ツール ウィンドウのタイトル バーは通常よりも短く、ウィンドウのタイトルはより小さいフォントで描画されます。タスク バーや、ユーザーが Alt キーを押しながら Tab キーを押して表示したウィンドウには、ツール ウィンドウは表示されません。
WS_EX_TOPMOSTこのスタイルで作成されたウィンドウは、すべてのウィンドウの上に配置され、アクティブでなくなった場合でも、引き続きほかのウィンドウの上に表示されたままになります。アプリケーションは、SetWindowPos メンバ関数を使って、この属性を追加および削除できます。
WS_EX_TRANSPARENTこのスタイルで作成されたウィンドウは透明になります。つまり、このウィンドウの下にあるウィンドウが見えなくなることはありません。このスタイルで作成されたウィンドウは、そのウィンドウの下にある兄弟ウィンドウがすべて更新された後にだけ、WM_PAINT メッセージを受け取ります。
WS_EX_WINDOWEDGE縁の浮き出した境界線を持つウィンドウを指定します。

・ウィンドウの外見や振る舞いを指定するパラメータには、ウィンドウ・スタイルの他に拡張ウィンドウ・スタイルがある。
これは、Windows95が登場した際に新たに定義されたもので、クライアント領域をウィンドウ枠よりもへこませて立体的に見せるかどうかといった点を指定できる。
・CreateWindowを使ってウィンドウを作成するのは、CreateWindowExの引数dwExStyleに0を指定して呼び出すのと同じである。
Windows > ウィンドウの作成 | comments (0) | trackbacks (0)

CreateWindow()関数


HWND CreateWindow(
 LPCTSTR lpClassName,
 LPCTSTR lpWindowName,
 DWORD dwStyle,
 int x,
 int y,
 int nWidth,
 int nHeight,
 HWND hWndParent,
 HMENU hMenu,
 HINSTANCE hInstance,
 LPVOID lpParam
);

ウィンドウハンドルは個々のウィンドウを識別するために使われるもので、
ウィンドウを操作する関数を呼び出す時に必要となります。

lpClassName登録済みのウィンドウクラス名
lpWindowNameウィンドウの名前
dwStyleウィンドウの種類や状態を表すビットフラグ
xウィンドウの初期位置
yウィンドウの初期位置
nWidthウィンドウの幅
nHeightウィンドウの高さ
hWndParent親ウィンドウのハンドル
hMenuメニューのハンドル
hInstanceWinMain()関数から取得したインスタンスハンドル
lpParam拡張用のパラメータ

使用例

#define CLASSNAME "Project_Name"
#define WINDOWNAME "TEST"
(中略)

HWND hWnd;

hWnd = CreateWindow( CLASSNAME, WINDOWNAME, WS_OVERLAPPEDWINDOW,
 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL );

if ( !hWnd ) {
 return FALSE;
}


●ウィンドウの構成要素に関するウィンドウ・スタイル
WS_CAPTIONタイトルバーを持つウィンドウを作成します。このスタイルを指定する場合は、WS_BORDERスタイルも指定する必要もあります。WS_DLGFRAMEスタイルと一緒に使うことはできません。
WS_BORDER境界線を持つウィンドウを作成します。細い(サイズ変更可能な)ウィンドウ枠です。
WS_DLGFRAME二重の境界線を持ち、タイトルは持たないウィンドウを作成します。ダイアログボックスで使用するウィンドウ枠です。
WS_THICKFRAME
WS_SIZEBOX
サイズ変更境界を持つウィンドウを作成します。太い(サイズ変更可能な)ウィンドウ枠です。
WS_HSCROLL水平スクロールバーを持つウィンドウを作成します。
WS_VSCROLL垂直スクロールバーを持つウィンドウを作成します。
WS_SYSMENUタイトルバーにコントロールメニューボックスを持つウィンドウを作成します。タイトルバーを持つウィンドウだけに指定します。WS_CAPTIONスタイルも指定する必要があります。
WS_MAXIMIZEBOX最大化ボタンを持つウィンドウを作成します。WS_SYSMENUと同時に指定する。
WS_MINIMIZEBOX最小化ボタンを持つウィンドウを作成します。WS_SYSMENUと同時に指定する。

●ウィンドウの種類に関するウィンドウ・スタイル
WS_OVERLAPPED
WS_TILED
オーバラップウィンドウを作成します。オーバラップウィンドウには、タイトルバーと境界線があります。
WS_POPUPポップアップウィンドウを作成します。WS_CHILDスタイルと一緒に使うことはできません。
WS_CHILD子ウィンドウを作成します。WS_POPUPスタイルと一緒に使うことはできません。
WS_OVERLAPPEDWINDOW
WS_TILEDWINDOW
WS_OVERLAPPED、WS_CAPTION、WS_SYSMENU、WS_THICKFRAME、WS_MINIMIZEBOX、WS_MAXIMIZEBOXスタイルを持つオーバラップウィンドウを作成します。
WS_POPUPWINDOWWS_BORDER、WS_POPUP、およびWS_SYSMENUスタイルを持つポップアップウィンドウを作成します。コントロールメニューを表示するには、WS_CAPTIONスタイルとWS_POPUPWINDOWスタイルを組み合わせて指定する必要があります。
WS_CHILDWINDOWWS_CHILDと同じ

●その他
WS_MINIMIZE
WS_ICONIC
初期状態で最小化されたウィンドウを作成します。必ずWS_OVERLAPPEDスタイルと一緒に使います。
WS_MAXIMIZE最大化されたウィンドウを作成します。
WS_VISIBLE初期状態で表示されるウィンドウを作成します。
WS_DISABLED初期状態で無効になっているウィンドウを作成します。
WS_TABSTOPダイアログボックスでTABキーを押した時に、コントロールが入力フォーカスを取得できるようにする。
WS_GROUPダイアログボックスでコントロールをグループ化する際に指定する。
WS_CLIPCHILDRENクライアント領域内の子ウィンドウのある部分を描画対象から除外する。
WS_CLIPSIBLINGS同じ親ウィンドウの子ウィンドウ同士で重なっている部分を描画対象から除外する。

ウィンドウ・スタイルはビット・フィールドとして定義されており、winuser.hなどのヘッダー・ファイルが定義する「WS_」で始まる定数を必要なだけ論理ORで組み合わせて指定する。

設定例
160_80_1.jpgWS_OVERLAPPEDWINDOW
サイズ変更可
160_80_2.jpgWS_POPUPWINDOW | WS_CAPTION
サイズ変更不可
160_80_3.jpgWS_POPUP | WS_BORDER | WS_CAPTION
サイズ変更不可
160_80_4.jpgWS_OVERLAPPEDWINDOW ^ WS_THICKFRAME ^ WS_MAXIMIZEBOX
サイズ変更不可
Windows > ウィンドウの作成 | comments (0) | trackbacks (0)