TreeView表示がおかしいです。

このQ&Aのポイント
  • Borland C++でWindowsAPIの練習中にTreeView表示がおかしい問題
  • フレームウィンドウの中に作成した子ウィンドウでTreeViewを表示しているが、正しく表示されない
  • TreeViewの作成時に設定すべきプロパティが抜けている可能性
回答を見る
  • ベストアンサー

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, ---------------------------------------------------------------------------------- 文字数表示制限のため、ここまでです。 宜しくお願いします。

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

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.3

>子ウィンドウにSendMessage ( hTree, WM_PAINT, NULL, NULL );メッセージを送ります。 このhTreeはどのウィンドウです? 掲示されているコードでは未設定(グローバル変数なので0(NULL))…のようですが? 親ウィンドウのWM_PAINTに対して、実際の描画を行わず子ウィンドウに投げるだけ…だと、親ウィンドウの表示が不正になります。 (子ウィンドウですべて覆ってしまえば見えないでしょう…が) また、BeginPaint()~EndPaint()で無効領域の解除を行っていませんので、OSから延々とWM_PAINTが飛んでくることになります。 # Borland C++ではSpy++は無いでしょうけど…Winspectorでメッセージの確認ができます。 子ウィンドウには「SendMessageでWM_PAINTを投げる」のではなく、InvalidateRect()などで無効領域を設定してOSに投げさせる…べきかと。 # もっとも、親ウィンドウにWM_PAINTが飛んできた時点でDefWindowProc()に任せればやってくれる…ハズですが。(子ウインドウのスタイルにも寄りますけど。) ……次は、コントロール(TreeView)がチラつく…でしょうかね? # ちゃんと親ウィンドウに乗っかっているから、親のWM_ERASEBKGNDの影響はない…かな??

dido123
質問者

お礼

おおお、まさしくその通りです。spy++で確認できました。 確かに永遠とWM_PAINTが飛んできています。 私の中では Cls_OnPaint(HWND hwnd){ } と親ウィンドウの中で設定すれば、それでWM_PAINT処理は終わりだと思っていました。 実際は無効領域の解除をしないと何度でもWM_PAINTが飛んできて永久ループ状態だったのですね。 親ウィンドウの処理 ----------------------------------------------------------------------- BOOL Cls_OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct) { RECT rc; HINSTANCE hInst; GetClientRect (hwnd, &rc); hInst = (HINSTANCE)GetWindowLong ( hwnd, GWL_HINSTANCE ); hTree = CreateWindowEx ( NULL, (LPCTSTR)"TreeWindow", NULL, WS_CHILD | WS_VISIBLE | WS_SIZEBOX, rc.left, rc.top, rc.left+200, rc.bottom, hwnd,NULL,hInst,NULL ); } void Cls_OnPaint(HWND hwnd) { PAINTSTRUCT ps; BeginPaint ( hwnd, &ps ); EndPaint ( hwnd, &ps ); } ----------------------------------------------------------------------- 子ウィンドウの処理 ----------------------------------------------------------------------- void Cls_OnTreeSize(HWND hwnd, UINT state, int cx, int cy) { MoveWindow (hwndTreeView, 0, 0, cx, cy, TRUE); } void Cls_OnTreePaint(HWND hwnd) { PAINTSTRUCT ps; BeginPaint ( hwnd, &ps ); EndPaint ( hwnd, &ps ); } ----------------------------------------------------------------------- とソースを変更して実行すると、希望していた通りの動きになりました。 「無効領域の解除」は大変、勉強になりました。 「Wr5」さん、何度も何度も的確なアドバイスありがとうございました。 今後とも、宜しくお願いいたします。

その他の回答 (2)

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.2

>void Cls_OnTreeSize(HWND hwnd, UINT state, int cx, int cy) >{ > MoveWindow (hwndTreeView, 0, 0, cx, cy, TRUE); >} コンパイル通りますか? hwndTreeViewの宣言がありませんけど? グローバル変数なのでしょうか? グローバル変数だとしても、この変数の中身は0(NULL)になっているかと思われますが… # Cls_OnTreePaint()の方も同様。 「Cls_OnTreeCreate()で設定している。」というのであれば、残念ながらそれはCls_OnTreeSize()やCls_OnTreePaint()には引き継がれません。 Cls_OnTreeCreate()内のローカル変数に設定しただけで、抜けた後には失われてしまうモノですから。 # 「ローカル変数に設定しているが大丈夫か?」と回答したんですが…。 # 「大丈夫だ、問題ない。」なんですか? Cls_OnTreeSize()で、ウィンドウサイズ全体にまでTreeViewを広げようとしていますが、実際に掲示された画像では広がっていませんよね? その関係で、Cls_OnTreePaint()も正しく動作していないのではありませんか?

dido123
質問者

補足

失礼しました。No1さんのご指摘を受け static HWND hwndTreeView; として、再利用できるようにしました。 Cls_OnTreeSize()は子ウィンドウ画面の全体に広げています。 将来的には、ドッキング可能な子ウィンドウにしようと考えています。 理由がわからないのですが、親ウィンドウでWM_PAINTを受け取った時に、子ウィンドウにSendMessage ( hTree, WM_PAINT, NULL, NULL );メッセージを送ります。子ウィンドウでWM_PAINTを受け取った処理を void Cls_OnTreePaint(HWND hwnd) { UpdateWindow (hwndTreeView); } と変更すると、不思議とすべての表示問題が解決されました。なぞです。 根本的な解決になっていないので、このまま、もう少し質問を継続としてご指摘を受けようと思います。

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.1

解決には役立たないと思いますが、気になったので指摘を。 >InitCommonControls();// コモンコントロールの初期化 WinMain()あたりでやっておけば良いです。 WM_CREATEのたびに実行が必要なモノではありません。 # 私ならInitCommonControlsEx()で初期化実施しますけど。 >hwndTreeView = CreateWindowEx( ここから抜けた後、TreeViewのウィンドウハンドルが不明になりますが大丈夫ですか? ID(ID_MYTREE)から取得は可能ですから、回避策自体はありますけど…。 実際のアイテム設定(挿入)部分、および描画をおこなっている部分が不明ですので…なんとも。

dido123
質問者

補足

ご助言ありがとうございます。実際のアイテム設定部分等が不明ではお答えできませんよね。 失礼致しました。以下、前回のソースの続きです。 --------------------------------------------------------------------------------- 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, &tv); tv.item.pszText = "田中"; hParent2 = TreeView_InsertItem(hwndTreeView, &tv); tv.item.pszText = "佐藤"; hParent3 = TreeView_InsertItem(hwndTreeView, &tv); tv.hParent = hParent1; tv.item.pszText = "康孝"; hChild1 = TreeView_InsertItem(hwndTreeView, &tv); tv.item.pszText = "ひとみ"; hChild2 = TreeView_InsertItem(hwndTreeView, &tv); tv.hParent = hChild1; tv.item.pszText = "志麻"; TreeView_InsertItem(hwndTreeView, &tv); tv.hParent = hChild1; tv.item.pszText = "櫻都"; TreeView_InsertItem(hwndTreeView, &tv); tv.hParent = hParent2; tv.item.pszText = "マイケル"; TreeView_InsertItem(hwndTreeView, &tv); tv.hParent = hParent3; tv.item.pszText = "パトリシア"; TreeView_InsertItem(hwndTreeView, &tv); } void Cls_OnTreeSize(HWND hwnd, UINT state, int cx, int cy) { MoveWindow (hwndTreeView, 0, 0, cx, cy, TRUE); } void Cls_OnTreePaint(HWND hwnd) { RECT rc; GetClientRect (hwnd, &rc); MoveWindow (hwndTreeView, rc.left, rc.top, rc.right, rc.bottom, TRUE); } /* void Cls_OnTReeClose(HWND hwnd) { DestroyWindow ( hwnd ); } void Cls_OnTReeDestroy(HWND hwnd) { PostQuitMessage ( 0 ); } */ -------------------------------------------------------------------------------- 以上です。 何かおかしな所がありましたら、ご教授お願いします。

関連するQ&A

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

    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; }

  • C++ WIN32 ウィドウの表示

    プログラミング初心者です。 WIN32APIの勉強を始めたばかりの状態です。 本を見ながら、ウィンドウを表示させるだけのプログラムを書いてみたのですが、エラーになってしまいます。 #include <windows.h> //ウィンドウ・クラス名 #define MYWNDCLSNAME "MyWindowClass" LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow) { WNDCLASS wndcls; HWND hWnd; MSG msg; //ウィンドウ・クラスを登録 ZeroMemory(&wndcls, sizeof(wndcls)); wndcls.lpfnWndProc = WndProc; wndcls.hInstance = hInst; wndcls.hIcon = LoadIcon(0, IDI_APPLICATION); wndcls.hCursor = LoadCursor(0, IDC_ARROW); wndcls.hbrBackground = (HBRUSH)COLOR_BACKGROUND; wndcls.lpszClassName = MYWNDCLSNAME; if(RegisterClass(&wndcls) == 0) return -1; //メイン・ウィンドウを作成 hWnd = CreateWindow(MYWNDCLSNAME, "My Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInst, NULL); if(hWnd == 0) return -2; //ウィンドウの表示状態を指定する ShowWindow(hWnd,nCmdShow); UpdateWindow(hWnd); //メッセージループ while(GetMessage(&msg, 0, 0, 0)){ DispatchMessage(&msg); } //WM_QUITメッセージのwParamを終了コードにする return msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg){ case WM_DESTROY: PostQuitMessage(0); return 0; } //自分で処理しないメッセージはWindowsに任せる return DefWindowProc(hWnd, uMsg, wParam, lParam); } 本を読み直しても原因がよくわかりません。 どこがいけないのかご指摘いただけるとうれしいです。お願いします。 エラーの内容は error C2440: '=' : 'const char [14]' から 'LPCWSTR' に変換できません。 error C2664: 'CreateWindowExW' : 2 番目の引数を 'const char [14]' から 'LPCWSTR' に変換できません。 です。

  • ウィンドウが表示されない

    あるサンプルプログラムを改造しようとしているのですが、g_hWnd=CreateWindow( _T(__FILE__),_T("シューティングゲーム"),WINDOW_STYLE, CW_USEDEFAULT,CW_USEDEFAULT,rc.right-rc.left,rc.bottom-rc.top, NULL,NULL,hInst,NULL);のところのWINDOW_STYLEをWS_OVERLAPPEDWINDOWに変えたらウィンドウが表示されません。どうしたら表示されるのでしょうか。わかる方いらいしたらご教授お願いします。多分ここだろうなというところのコードを載せます。 LRESULT CALLBACK MainWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam) { switch(msg) { case WM_KEYDOWN: switch(wParam) { case VK_F1: ChangeDisplayMode(); return 0; case VK_ESCAPE: PostMessage(hWnd,WM_CLOSE,0,0); return 0; } return 0; case WM_DISPLAYCHANGE: // IDirect3DDevice9::Reset メソッドから Send される DisplayChange(); return 0; case WM_SIZE: if(g_bWndMode==false || wParam==SIZE_MINIMIZED) return 0; g_D3DPP.BackBufferWidth = LOWORD(lParam); g_D3DPP.BackBufferHeight = HIWORD(lParam); if(wParam==SIZE_MAXIMIZED || wParam==SIZE_RESTORED) ChangeWindowSize(); return 0; case WM_ACTIVATE: g_bActive=(LOWORD(wParam)!=WA_INACTIVE); return 0; case WM_DESTROY: CleanupD3DObject(); CleanupDXGraphics(); PostQuitMessage(0); return 0; } return DefWindowProc(hWnd,msg,wParam,lParam); }

  • 別関数に渡す変数のポインタが難しい

    構造体初心者で、ポインタもよく分かっていません。 12, 8 と表示するつもりのソースだけど、実行結果は違っていました。 直してください。 ソースは長いけど、スケルトンに構造体とTextOutを付けたぐらいのものです。 #include <windows.h> struct MYOBJ { int a; int b; }; LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int) { MSG msg; WNDCLASS wc; 投稿できなかったからここを消しました。 wc.lpszClassName = "x"; if(RegisterClass(&wc) == 0)return 0; HWND hWnd = CreateWindow("x","",WS_OVERLAPPEDWINDOW|WS_VISIBLE,0,0,320,240,NULL,NULL,hInst,NULL); while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } void myfunc(struct MYOBJ *obj)//ここが違うかもしれません。 { obj->a += 2; obj->b -= 2; } LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { HDC hDC; PAINTSTRUCT ps; char buf[30]; switch(uMsg) { case WM_CREATE: struct MYOBJ myobj; myobj.a = 10; myobj.b = 10; myfunc(&myobj);//ここが違うかもしれません。 return 0; case WM_PAINT: hDC = BeginPaint(hWnd, &ps); wsprintf(buf, "%d, %d", myobj.a, myobj.b); TextOut(hDC, 0, 0, buf, strlen(buf)); EndPaint(hWnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } return 0; }

  • 何もしないメッセージだけ表示するウィンドウ

    ゲーム用に何もしないメッセージだけ表示するウィンドウを作りたいのですが、 猫でもわかるゲームプログラミングのコードが間違っているのか、 機能しません。 #include <windows.h> LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp); int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { return (int)msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { switch (msg){ } return 0; } このように、打ち込んだのですが、どこが間違っているのか解りません。 回答お願いいたします。

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

    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); } }

  • ShellAbout(hWnd,"","",LoadIcon(?));

    BCC32 で、 ShellAbout(hWnd,"","",LoadIcon(hInst, IDI_APPLICATION)); ShellAbout(hWnd,"","",LoadIcon(NULL, IDI_APPLICATION)); ↑ならアイコンに関してどっちでもできるけど、リソースで MYICONSM ICON DISCARDABLE "ico.ico" として、 ShellAbout(hWnd,"","",LoadIcon(hInst, "MYICON"); ShellAbout(hWnd,"","",LoadIcon(NULL, "MYICON")); ↑はアイコンに関してどっちも無効で旗になります。 BCC32 で ShellAbout( ) で自作アイコンを表示するには どうしたらいいんですか? #include <windows.h> #include <shellapi.h> HINSTANCE hInst; HICON hIcon; LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam){  switch (uMsg){  case WM_LBUTTONDOWN:   ShellAbout(hWnd,"","",?;  break;  case WM_DESTROY:   PostQuitMessage(0);  break;  default:   return DefWindowProc(hWnd,uMsg,wParam,lParam);  }  return 0; } int WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR,int){  HWND hWnd;  WNDCLASSEX wc;  MSG msg;  wc.cbSize =略  wc.style =  wc.lpfnWndProc =  wc.hInstance =  wc.cbClsExtra =  wc.cbWndExtra =  wc.lpszMenuName =  wc.lpszClassName =  wc.hIcon =  wc.hCursor =  wc.hbrBackground =  RegisterClassEx(&wc);  hWnd = CreateWindow(wc.lpszClassName,"TEST",WS_OVERLAPPEDWINDOW,      0,0,640,480,NULL,NULL,hInst,NULL);  ShowWindow(hWnd,SW_SHOWNORMAL);  UpdateWindow(hWnd);  while(GetMessage( &msg, NULL, 0, 0)){   TranslateMessage( &msg );   DispatchMessage( &msg );  }  return 0; }

  • ダイアログ表示後に1回だけ実行

    ダイアログベースのプログラムで、ダイアログを表示後にメッセージボックスを表示しようとして、下のプログラムのようにしたのですがダイアログが表示される前にメッセージボックスが表示されてしまいます。 ダイアログが表示された直後に1回だけ表示されるようにするにはどうすればいいですか? #include<Windows.h> #include "resource.h" HINSTANCE hinst; INT_PTR CALLBACK dlgproc(HWND,UINT,WPARAM,LPARAM); int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) { hinst=hInstance; DialogBox(hinst,TEXT("mydlgmain"),NULL,dlgproc); } INT_PTR CALLBACK dlgproc(HWND hwnd,UINT msg,WPARAM wp,LPARAM lp) { TCHAR moji[]=TEXT("ダイアログ表示"); switch(msg) { case WM_INITDIALOG: MessageBox(hwnd,moji,TEXT(""),MB_OK); return(INT_PTR)TRUE; case WM_CLOSE: EndDialog(hwnd,LOWORD(wp)); return (INT_PTR)TRUE; } return(INT_PTR)FALSE; } --- 実行環境 --- Microsoft Visual C++ 2010 Express WIN32 ユニコードビルド C言語

  • CTreeCtrlのCreate関数でエラーになります。

    Visual C++ .NET Win32 プロジェクト で、アプリケーションを作成しようと思っています。 #include<afxwin.h> #include<afxcmn.h> // マルチスレッド CTreeCtrl *m_TreeCtrl; LRESULT CALLBACK int WindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { switch(message) { case WM_LBUTTONDOWN: m_TreeCtrl=new CTreeCtrl; m_TreeCtrl->Create(WS_VISIBLE | WS_TABSTOP | WS_CHILD | WS_BORDER | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_HASLINES | TVS_DISABLEDRAGDROP, CRect(10, 10, 300, 100), CWnd::FromHandle(hWnd), 10000); break; case WM_CREATE: break; case WM_DESTROY: PostQuitMessage(0); break; case WM_PAINT: HDC hDC; PAINTSTRUCT Paint; hDC=BeginPaint(hWnd,&Paint); EndPaint(hWnd,&Paint); } return DefWindowProc(hWnd,message,wParam,lParam); } ・・・ と記述すると、エラーになります。 解決方法を教えてください。

  • 自作関数の使い方

    ウインドウの左上に1を表示させたいのに デスクトップの左上に1が表示される。 ソースを直してください。 #include <windows.h> HWND hWnd; void f(); LRESULT CALLBACK WndProc(HWND ,UINT ,WPARAM ,LPARAM); int WINAPI WinMain(HINSTANCE hInstance ,HINSTANCE ,LPSTR , int){  HWND hWnd;  MSG msg;  WNDCLASS wc;  wc.style = CS_HREDRAW | CS_VREDRAW;  wc.lpfnWndProc = WndProc;  wc.cbClsExtra = wc.cbWndExtra = 0;  wc.hInstance = hInstance;  wc.lpszMenuName = NULL;  wc.lpszClassName = "CNAME";  wc.hIcon = LoadIcon(NULL , IDI_APPLICATION);  wc.hCursor = LoadCursor(NULL , IDC_ARROW);  wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);  if (!RegisterClass(&wc))return 0;  hWnd = CreateWindow(wc.lpszClassName , "EXE" ,   WS_OVERLAPPEDWINDOW | WS_VISIBLE ,   CW_USEDEFAULT , CW_USEDEFAULT , 200 , 150,   NULL , NULL , hInstance , NULL);  while(GetMessage(&msg , NULL , 0 , 0)){   TranslateMessage(&msg);   DispatchMessage(&msg);  }  return msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd ,UINT msg ,WPARAM wParam ,LPARAM lParam){  HDC hDC;  switch (msg){  case WM_LBUTTONDOWN:   f();  break;  case WM_DESTROY:   PostQuitMessage(0);  break;  default:   return(DefWindowProc(hWnd , msg , wParam , lParam));  }  return (0L); } void f(){  HDC hDC;  hDC = GetDC(hWnd);  TextOut(hDC,0,0,"1",1);  ReleaseDC(hWnd, hDC); }