• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:CREATESTRUCT と GetWindowLong)

CREATESTRUCTとGetWindowLongの違いと意味について教えてください

このQ&Aのポイント
  • CREATESTRUCTとは、ウィンドウが作成される際に使用される構造体のことです。一方、GetWindowLongは指定されたウィンドウの情報を取得するための関数です。
  • CREATESTRUCTは、ウィンドウの作成時に必要な情報を格納するために使用されます。一方、GetWindowLongは、指定されたウィンドウの指定された情報を取得するために使用されます。
  • CREATESTRUCTは、ウィンドウが作成される際に使用される構造体であり、ウィンドウの作成時に必要な情報を格納します。一方、GetWindowLongは、指定されたウィンドウの指定された情報を取得するための関数です。

質問者が選んだベストアンサー

  • ベストアンサー
  • a-kuma
  • ベストアンサー率50% (1122/2211)
回答No.2

No.1 の wr250zb さんと同じような回答しかできませんが、参考まで。 GetWindowLong() を使う場合には、ウィンドウハンドルが取得できているもの全てに 対してインスタンスハンドルを取得できますが、lParam からインスタンスハンドルを 取得するのは、WndProc が属するアプリケーションだけで、かつ、WM_CREATE メッセージが 発生したときだけ、という制限があります。 試したわけではないのと、純粋な Win32 アプリケーションを組まなくなって久しいので 自信がありませんが、WM_CREATE メッセージが出ているときにはウィンドウが生成中なので GetWindowLong() を使ってインスタンスハンドルを取得できないかもしれません。 WinMain() と WndProc() が同じスコープにあれば、静的な変数を媒介してインスタンス ハンドルを受け渡せば良いのかもしれませんが。

A__
質問者

お礼

ありがとうございます。 WM_CREATE の前でなら GetWindowLong() しか使えず、 WM_CREATE の後でならどちらも使えるということですね。 CREATESTRUCT は WM_CREATE の後でも使えました。 WM_CREATE の中で GetWindowLong() を使うこともできました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (1)

  • wr250zb
  • ベストアンサー率41% (7/17)
回答No.1

どちらもアプリケーションのインスタンスハンドルを取得しています。 CREATESTRUCTで取るのはWM_CREATEメッセージが来たとき のパラメータ(lParam)からアクセスしています。 GetWindowLongはhWndで指定したウィンドウに対して 指定した(この場合GWL_HINSTANCE)種類の4バイト データを要求しています。指定した値の種類がGWL_HINSTANCEなんでインスタンスハンドル値が 戻って来ます。 で、細かい部分とは?

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • ハンドルからインスタンス?を取得したいのですが

    CreateWindowExを使いたいのですが 途中でインスタンス?(でいいのかな?)を指定するところが あるのですがどうしていいか困っています。 GetWindowLong(HWND,GWL_HINSTANCE); でとれるのかな?と思うのですが 返す値がLongです インスタンスにキャストすることなどできるのでしょうか? どのようにしたらいいのでしょうか? インスタンス自身もあまり意味が....... よろしくお願いいたします

  • VC++コンソールアプリでのインスタンスハンドルの取得

    VC++コンソールアプリでのインスタンスハンドルの取得 VC++コンソールアプリケーションでインスタンスハンドルを取得しようとしているのですが、 HINSTANCE hi = (HINSTANCE)GetWindowLong(HWND_DESKTOP, GWL_HINSTANCE); を実行すると、NULLが戻ってきます。 どこかまずい部分があるのでしょうか。 なお、第一引数のウィンドウハンドルは不明なため、 いくつかのWebサイトに習い、HWND_DESKTOPを指定しました。

  • GetModuleFileNameでエラーが出てしまう。

    #include<windows.h> #include<string.h> // 関数のプロトタイプ宣言 VOID CALLBACK TimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime); BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam); // エントリポイント int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; EnumWindows((WNDENUMPROC)EnumWindowsProc,NULL); while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam) { char Caption[201]; char FileName[1024]=""; char FindList[1][80]={"Microsoft Internet Explorer"}; GetWindowText(hwnd, Caption, 200); for(int i=0;i<=0;i++) if(NULL!=strstr(Caption,FindList[i])) { HINSTANCE hInst; hInst = (HINSTANCE)GetWindowLong(hwnd,GWL_HINSTANCE); if(GetModuleFileName(hInst, FileName, 1023)!=0) { // ファイル名取得成功したときの動作 MessageBox(NULL,Caption,FileName,MB_OK|MB_SETFOREGROUND); }else{ MessageBox(NULL,Caption,"Error",MB_OK|MB_SETFOREGROUND); } } return true; } 実行するとIEが起動されてたらそのウインドウのキャプションとプログラム名を表示される予定なのですが、 GetModuleFileNameでエラーが返されます。 何が原因なのでしょう?

  • GetModuleFileName(他のアプリ, buf, 255);

    HINSTANCE hInst; hInst = (HINSTANCE)GetWindowLong(hWndElse, GWL_HINSTANCE); GetModuleFileName(hInst, buf, 255); というソースで、buf[0] が 0 でした。 GetWindowText( ) のように、GetModuleFileName( ) も 他のアプリに対しては 0 を返すんですか?

  • ツールバーにうまく文字が付けられません

    いつもお世話になっています。よろしくお願いします。 色々調べて、自分なりに改良したのですが、原因がつかめません。 アドバイス、ヒントをお願いします。 ツールバーの『windows標準のボタン』に、『文字を付ける』部分で躓いています。   //ツールバー作成関数 HWND MyCreateToolbar(HWND hWnd) { HINSTANCE hInst; HWND hTool; TBADDBITMAP tb; int stdid; hInst = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE); hTool = CreateToolbarEx( hWnd, WS_CHILD | WS_VISIBLE, ID_TOOLBAR, // コントロールID 0, hInst, NULL, tbb, 0, 0, 0, 0, 0, sizeof(TBBUTTON)); tb.hInst = HINST_COMMCTRL; tb.nID = IDB_STD_SMALL_COLOR; stdid = SendMessage(hTool, TB_ADDBITMAP, 0, (LPARAM)&tb); tbb[0].iBitmap += stdid; tbb[1].iBitmap += stdid; tbb[2].iBitmap += stdid; SendMessage(hTool, TB_ADDBUTTONS, (WPARAM)3, (LPARAM)&tbb[0]); tb.hInst = HINST_COMMCTRL; tb.nID = IDB_VIEW_SMALL_COLOR; stdid = SendMessage(hTool, TB_ADDBITMAP, 0, (LPARAM)&tb); tbb[3].iBitmap += stdid; SendMessage(hTool, TB_ADDBUTTONS, (WPARAM)1, (LPARAM)&tbb[3]); } //ここでくくると、『ボタンに文字を付ける関数』が機能しない //『}』 を、『ボタンに文字を付ける関数』の最後につけると、文字が表示されるが、エラーが出る。 //エラー E2108 c:\ツールバー\toolbar\toolbar.cpp 201: typedef 'HWND' の使い方が間違っている(関数 MyCreateToolbar(HWND__ *) ) エラー E2379 c:\ツールバー\toolbar\toolbar.cpp 201: ステートメントにセミコロン(;)がない(関数 MyCreateToolbar(HWND__ *) ) *** 2 errors in Compile *** /ボタンに文字を付ける関数 HWND MyCreateToolbar(HWND hWnd); //;セミコロンをつけないと //HWNDの使い方が間違っている ステートメントにセミコロンが無い の エラー { HINSTANCE hInst; HWND hTool; TCHAR szBuf[16]; int iNEW; int iOPEN; int iPARENT; int iDELETE; TBADDBITMAP tbab; InitCommonControls(); hInst = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE); hTool = CreateWindow(TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hWnd, (HMENU)ID_TOOLBAR, hInst, NULL); SendMessage(hTool, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0); tbab.hInst = HINST_COMMCTRL; //既成はCOMMCTRL 自作ビットマップはNULL tbab.nID = IDB_STD_SMALL_COLOR; ID_TOOLBAR; SendMessage(hTool, TB_ADDBITMAP, (WPARAM)0, (LPARAM)&tbab); LoadString (hInst, IDS_NEW, szBuf, (TCHAR)sizeof(szBuf)); iNEW = SendMessage(hTool, TB_ADDSTRING, 0, (LPARAM)szBuf); tbb[0].iString = iNEW; LoadString (hInst, IDS_OPEN, szBuf, (TCHAR)sizeof(szBuf)); iOPEN = SendMessage(hTool, TB_ADDSTRING, 0, (LPARAM)szBuf); tbb[1].iString = iOPEN; LoadString (hInst, IDS_DELETE, szBuf, (TCHAR)sizeof(szBuf)); iDELETE = SendMessage(hTool, TB_ADDSTRING,0, (LPARAM)szBuf); tbb[2].iString = iDELETE; LoadString (hInst, IDS_PARENT, szBuf, (TCHAR)sizeof(szBuf)); iDELETE = SendMessage(hTool, TB_ADDSTRING, 0, (LPARAM)szBuf); tbb[3].iString = iPARENT; SendMessage(hTool, TB_ADDBUTTONS, (WPARAM)3, (LPARAM)(LPTBBUTTON)&tbb[0]); return hTool; } } ツールバー作成関数を 『}』で閉じると 文字を付ける関数が機能せず、標準のボタンが4つ表示されます。 『}』 を『文字を付けるをつける関数』の最後に付けると文字が表示されるが、『ツールバー作成関数』の所で閉じていないので、エラーが出ます。 『}』 を『文字を付けるをつける関数』の最後に付けると ボタン二つ分の大きさの『文字だけのボタンが最初に表示されたボタン4つを隠して3種類だけ表示されます。(新規作成、開く、削除) このとき、新規作成などの文字の上の部分をクリックすると、隠れていたボタンが出てきます。 その出てきたボタンもクリックできます。文字をクリックすると、ボタンは、隠れてしまいます。 VC++で『文字を付けるをつける関数』は、エラー、警告が出て作れません。

  • ウィンドウの作成がうまくいきません。

    C++で一からWin32Apiでウィンドウを作ろうとしています。 単発のウィンドウ表示はうまくいったのですが、複数のウィンドウを表示しようとすると動作が怪しくなります。 以下にプログラムを載せさせて頂きますのでご指摘お願いします。 (1)LRESULT C_BaseWnd::LocalWindProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)の関数でメインウィンドウの処理を行っているのですが、メインウィンドウ上で「a(0x61)」キーを入力したとき新しくサブウィンドウを表示させています。その表示したサブウィンドウを閉じて再度メインウィンドウから「a(0x61)」キーを入力してサブウィンドウを表示しようとしても応答がありません。原因と改善方法を教えていただけるとうれしいです。 (2)そのほか全体的に「この記述おかしいだろう」「こうしたほうがいいんじゃないか」など細かいところでも良いので教えていただけるとうれしいです。 よろしくお願いします。 #include <Windows.h> class C_BaseWnd { public: C_BaseWnd(); virtual ~C_BaseWnd(); virtual HRESULT Init( HINSTANCE hInst, int nCmdShow, LPTSTR className, LPTSTR windowName, UINT width, UINT height, DWORD style, BOOL windowFlag ); virtual void Uninit(void); protected: WNDCLASSEX m_wndClassEx; HWND m_hWnd; // 親のウィンドウプロシージャ virtual LRESULT LocalWindProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); // 子のウィンドウプロシージャ virtual LRESULT ChildWindProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); private: // 個々のウィンドウプロシージャを呼び出すコールバック static LRESULT CALLBACK s_CallWindProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); // メインウィンドウフラグ格納 bool m_bMain; }; int WINAPI WinMain( HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow ) { // 初期化処理 C_BaseWnd *window = new C_BaseWnd(); window->Init( hCurInst, nCmdShow, "Application Name", "Window Name", 1280, 720, WS_OVERLAPPEDWINDOW, true ); MSG msg; while( GetMessage(&msg, NULL, 0, 0) ) { TranslateMessage(&msg); DispatchMessage(&msg); } window->Uninit(); delete window; return 0; } C_BaseWnd::C_BaseWnd() { m_hWnd = NULL; m_bMain = false; } C_BaseWnd::~C_BaseWnd() { } HRESULT C_BaseWnd::Init(HINSTANCE hInst, int nCmdShow, LPTSTR className, LPTSTR windowName, UINT width, UINT height, DWORD style, BOOL windowFlag) { m_wndClassEx.cbSize = sizeof(WNDCLASSEX); m_wndClassEx.lpfnWndProc = s_CallWindProc; m_wndClassEx.style = (CS_HREDRAW | CS_VREDRAW); m_wndClassEx.cbClsExtra = 0; m_wndClassEx.cbWndExtra = 0; m_wndClassEx.hInstance = hInst; m_wndClassEx.hIcon = NULL; m_wndClassEx.hCursor = LoadCursor(NULL, IDC_ARROW); m_wndClassEx.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); m_wndClassEx.lpszMenuName = NULL; m_wndClassEx.lpszClassName = className; m_wndClassEx.hIconSm = NULL; if( RegisterClassEx(&m_wndClassEx) == 0 ) return E_FAIL; m_hWnd = CreateWindowEx( 0, className, windowName, style, CW_USEDEFAULT, CW_USEDEFAULT, width, height, NULL, NULL, hInst, NULL); if( m_hWnd == NULL ) return E_FAIL; // 自身をウィンドウハンドルにセットする SetWindowLong( m_hWnd, GWL_USERDATA, (LONG)this ); ShowWindow(m_hWnd, nCmdShow); UpdateWindow(m_hWnd); if( windowFlag ) m_bMain = true; return S_OK; } void C_BaseWnd::Uninit(void) { UnregisterClass(m_wndClassEx.lpszClassName, m_wndClassEx.hInstance); } LRESULT C_BaseWnd::LocalWindProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch( msg ) { case WM_CHAR: if( wParam == 0x61 ) { // サブウィンドウ初期化処理 C_BaseWnd *window2 = new C_BaseWnd(); window2->Init( (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), SW_SHOW, "Application Name2", "Window Name2", 1920, 1080, WS_OVERLAPPEDWINDOW, false ); } break; case WM_DESTROY: PostQuitMessage(0); break; default: break; } return DefWindowProc(hWnd, msg, wParam, lParam); } LRESULT C_BaseWnd::ChildWindProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch( msg ) { case WM_CHAR: break; case WM_CLOSE: break; default: break; } return DefWindowProc(hWnd, msg, wParam, lParam); } LRESULT CALLBACK C_BaseWnd::s_CallWindProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { // セットした個別のインスタンスを取得 C_BaseWnd *pInst = (C_BaseWnd *)GetWindowLong(hWnd, GWL_USERDATA); if( !pInst ) { return DefWindowProc(hWnd, msg, wParam, lParam); } if( pInst->m_bMain ) { return pInst->LocalWindProc(hWnd, msg, wParam, lParam); } else { return pInst->ChildWindProc(hWnd, msg, wParam, lParam); } }

  • win32 GetWindowLong

    GetWindowLongで別のプログラムのウインドウハンドルを取得してウィンドウプロシージャのアドレスを調べようと思ったのですが取得できません。他のウィンドウのウィンドウプロシージャのアドレスは取得できないのでしょうか? ------------------------------------------ #include <stdio.h> #include <string.h> #include <windows.h> struct cell{ HWND hWnd; char WindowName[256]; }; BOOL CALLBACK EnumWndProc( HWND hWnd, LPARAM lParam ) { char buff[256]=""; GetWindowText( hWnd,buff, sizeof(buff));//ウインドウの文字を取得して、 if(strcmp(buff,((cell*)lParam)->WindowName)==0){//名前が一致したら、 ((cell*)lParam)->hWnd = hWnd;//ウィンドウハンドルを渡す } return true; } int main(int argc, char* argv[]) { cell c; c.hWnd =NULL; strcpy(c.WindowName,"無題 - メモ帳");//検索するウィンドウの名前 EnumWindows( EnumWndProc, (LPARAM)&c); LONG wndproc, exstyle; if(c.hWnd != NULL){ //目的のウインドウハンドルが取得できました wndproc = GetWindowLong(c.hWnd, GWL_WNDPROC); //メモ帳のウィンドウプロシージャが取得できない exstyle = GetWindowLong(c.hWnd, GWL_EXSTYLE); } return 0; }

  • ビットマップの描画について(Windowプログラミング)

    おせわになります。 現在WIndows上で動作するソフトを作成しています。 ほとんど作成は終わっているのですが、作成したWindowsの上にビットマップを描画する部分で不安な点があります。 (これまであまり手をつけていなかったので) ネットなどを参考に作成したのですが、サンプルコードを見ていただいておかしいところを指摘していただければ幸いです。 以下のようなコードになります。 int ShowBMP(HWND hWnd, HDC hdc) { HDC hmdc; HBITMAP hBitmap; BITMAP bmp; HINSTANCE hInst; int BMP_W, BMP_H; hInst = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE); hBitmap = LoadBitmap(hInst, "TOPBMP"); GetObject(hBitmap, sizeof(BITMAP), &bmp); BMP_W = (int)bmp.bmWidth; BMP_H = (int)bmp.bmHeight; hmdc = CreateCompatibleDC(hdc); SelectObject(hmdc, hBitmap); BitBlt(hdc, 0, 0, BMP_W, BMP_H, hmdc, 0, 0, SRCCOPY); DeleteDC(hmdc); DeleteObject(hBitmap); return 1; }

  • TreeView表示がおかしいです。

    Borland C++ (WindowsXP SP3)でWindowsAPIの練習中の人です。 メインウィンドウ(フレームウィンドウ)の中に子ウィンドウを作成してます。 その子ウィンドウの中でTreeView表示しているのですが、下の画像の様な表示になってしまいます。 何かお気づきになりましたら、ご教授お願いします。 一部、ソースを抜粋します。 ---------------------------------------------------------------------------------- #include "header.h" // ヘッダーファイル LRESULT CALLBACK TreeWndProc ( HWND, UINT, WPARAM, LPARAM ); BOOL Cls_OnTreeCreate(HWND, LPCREATESTRUCT); void Cls_OnTreeSize(HWND, UINT, int, int ); void Cls_OnTreePaint(HWND); static HWND hTree; LRESULT CALLBACK TreeWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch ( msg ) { HANDLE_MSG(hWnd, WM_CREATE, Cls_OnTreeCreate); HANDLE_MSG(hWnd, WM_SIZE, Cls_OnTreeSize); HANDLE_MSG(hWnd, WM_PAINT, Cls_OnTreePaint); default: return ( DefWindowProc ( hWnd, msg, wParam, lParam ) ); } return 0L; } BOOL Cls_OnTreeCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct) { RECT rc; HINSTANCE hInst; HWND hwndTreeView; HTREEITEM hParent1, hParent2, hParent3, hChild1, hChild2; TV_INSERTSTRUCT tv; InitCommonControls(); // コモンコントロールの初期化 GetClientRect (hwnd, &rc); hInst = (HINSTANCE)GetWindowLong ( hwnd, GWL_HINSTANCE ); hwndTreeView = CreateWindowEx( 0, WC_TREEVIEW, "", WS_CHILD | WS_BORDER | WS_VISIBLE | TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT, rc.left, rc.top, rc.right,rc.bottom, // 0,0,0,0, hwnd, (HMENU)ID_MYTREE, hInst, NULL ); TreeView_SetBkColor (hwndTreeView,RGB(0,0,0)); TreeView_SetTextColor (hwndTreeView,RGB(255,255,255)); TreeView_SetLineColor (hwndTreeView,RGB(125,125,255)); memset((char *)&tv, '\0', sizeof(tv)); tv.hInsertAfter = TVI_LAST; tv.item.mask = TVIF_TEXT; tv.hParent = TVI_ROOT; tv.item.pszText = "粂井"; hParent1 = TreeView_InsertItem(hwndTreeView, ---------------------------------------------------------------------------------- 文字数表示制限のため、ここまでです。 宜しくお願いします。

  • 子ウインドウの作成と破棄について

    CALLBACK のみを書きました。 メインウインドウを破棄したら 子ウインドウも破棄したいのですが、 うまく出来ません。 どうすればよろしいでしょうか? よろしくお願いします。 #include<windows.h> #include"ChildWindow.h" char MainWindowClassName[]="mainwindow"; LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { static HWND childWnd; switch(message) { case WM_ACTIVATEAPP: childWnd=Child_CreateWindow(hWnd,message,wParam,lParam); break; case WM_DESTROY: DestroyWindow(childWnd); PostQuitMessage(0); break; default: return DefWindowProc(hWnd,message,wParam,lParam); } } ///////////////////////////////////////////// #include<windows.h> char ChildWindowClassName[]="childwindow"; LRESULT CALLBACK ChildProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { switch(message) { case WM_LBUTTONDOWN: MessageBox(NULL,"","",MB_OK); break; default: return DefWindowProc(hWnd,message,wParam,lParam); } } ATOM Child_RegistWindow(HINSTANCE hInstance){} HWND Child_InitInstance(HWND hParentWnd,HINSTANCE hInst,int CmdShow){} HWND Child_CreateWindow(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { int CmdShow=1; Child_RegistWindow(NULL); HWND ChildWnd=Child_InitInstance(hWnd,NULL,CmdShow); MSG msg; while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return ChildWnd; }

印刷した用紙がつまり取れない
このQ&Aのポイント
  • パソコンからカーラー印刷の指示し印刷を始めたのですが途中で止まり、紙づまり、本体と後ろ側も開けた取ろうとしたのですが用紙にゆとりがなく敗れて取れません。
  • 印刷した用紙がつまり取れない問題に遭遇しました。パソコンから印刷を開始しましたが、途中で止まり、紙づまりが発生しました。本体と後ろ側を開けて解決を試みましたが、用紙にゆとりがなく取り除くことができませんでした。
  • 印刷した用紙がつまり取れない問題に直面しました。カーラー印刷を指示して印刷を開始した際に、途中で印刷が止まりました。紙づまりが発生し、用紙を取り外すことができませんでした。本体と後ろ側を開けて解決を試みましたが、用紙にゆとりがなかったため、取り除くことができませんでした。
回答を見る

専門家に質問してみよう