ウィンドウのサイズ変更について

このQ&Aのポイント
  • ウィンドウのサイズ変更方法を紹介します
  • ウィンドウサイズの変更に関する問題を解決する方法を提案します
  • WindowsAPIを使用して、マウスで指定数動いた時にウィンドウをサイズ変更する方法を説明します
回答を見る
  • ベストアンサー

ウィンドウのサイズ変更について

ウィンドウのサイズ変更について質問です。 ウィンドウをサイズ変更する際に、マウスで指定数動いた時だけ サイズ変更するようにしたいのですが、何か方法はあるのでしょうか? ちなみに、 拡張ウィンドウスタイルは、 WS_EX_TOOLWINDOW | WS_EX_LAYERED | WS_EX_ACCEPTFILES ウィンドウスタイルは、 WS_POPUPWINDOW | WS_CLIPCHILDREN です。 「WS_THICKFRAME」を使用してやろうとしたのですが出来ませんでした。 何か方法があるのかもしれませんが。 開発環境 XP Visual Studio 2005 C、C++でWindowsAPIを使用しています。

noname#154655
noname#154655

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

  • ベストアンサー
回答No.5

 こんにちは。御礼頂きました。  予期せぬ事態がおきるとWM_CANCELMODEが送られてくるので、此処でキャプチャが外れてしまった時の処理をします。  又、マウスがリサイズ領域に当たった時のカーソル変更等も自力で行う必要があります(今回此れは省略しています)。  大体こんな感じです。 #include<windows.h> #include<commctrl.h> #include<tchar.h> #pragma comment(lib, "comctl32.lib") const DWORD WS_EX_LAYERED = 0x80000; static LPARAM s_hitState = HTNOWHERE; //ウィンドウクラス登録 static ATOM Regist(LPCTSTR szClassName, WNDPROC wndProc) { WNDCLASSEX wndclass = {sizeof(wndclass)}; wndclass.hCursor = ::LoadCursor(NULL,IDC_ARROW); wndclass.hIcon = NULL; wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szClassName; wndclass.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH); wndclass.hInstance = ::GetModuleHandle(NULL); wndclass.style = 0; wndclass.lpfnWndProc = wndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; return ::RegisterClassEx(&wndclass); } //ウィンドウを作成して開く static HWND OpenWindow(LPCTSTR szClassName, LPCTSTR szTitleName, INT w, INT h, LPVOID pData) { HINSTANCE hInst = ::GetModuleHandle(NULL); HWND hWnd = ::CreateWindowEx(WS_EX_TOOLWINDOW | /*WS_EX_LAYERED |*/ WS_EX_ACCEPTFILES, szClassName, szTitleName, WS_POPUPWINDOW | WS_CLIPCHILDREN,// | WS_THICKFRAME, CW_USEDEFAULT,CW_USEDEFAULT, w, h, NULL, NULL, hInst, pData); return hWnd; } static LRESULT OnCreate(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return 0; } static LRESULT OnClose(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { ::DestroyWindow(hWnd); return 0; } static LRESULT OnNCDestroy(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { ::PostQuitMessage(0); return 0; } static LRESULT OnCancelMode(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { s_hitState = HTNOWHERE; return 0; } static LRESULT OnLButtonDown(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { //リサイズ枠と見なす幅 LONG ResizeEdge = 4; //マウス位置を取る POINT pt; ::GetCursorPos(&pt); //ウィンドウ位置を取る RECT rc = {0}; ::GetWindowRect(hWnd, &rc); //リサイズ枠の位置ではないと見なす if(pt.x < rc.right - ResizeEdge && pt.y < rc.bottom - ResizeEdge) return 0; if(pt.x >= rc.right - ResizeEdge && pt.y >= rc.bottom - ResizeEdge) { s_hitState = HTBOTTOMRIGHT; } else if(pt.x >= rc.right - ResizeEdge) { s_hitState = HTRIGHT; } else if(pt.y >= rc.bottom - ResizeEdge) { s_hitState = HTBOTTOM; } //キャプチャをする ::SetCapture(hWnd); return 0; } static LRESULT OnLButtonUp(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { //キャプチャを解く s_hitState = HTNOWHERE; ::ReleaseCapture(); return 0; } static LRESULT OnMouseMove(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { //移動量 LONG lPct = 16; //キャプチャされてないので引き返す if(s_hitState == HTNOWHERE) return 0; POINT pt; ::GetCursorPos(&pt); RECT rc = {0}; ::GetWindowRect(hWnd, &rc); switch(s_hitState) { case HTRIGHT: case HTBOTTOMRIGHT: //横に対して if(((pt.x - rc.right) % lPct) == 0) { ::SetWindowPos(hWnd, NULL, 0, 0, pt.x - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER); } }; switch(s_hitState) { case HTBOTTOM: case HTBOTTOMRIGHT: //縦に対して if(((pt.y - rc.bottom) % lPct) == 0) { ::SetWindowPos(hWnd, NULL, 0, 0, rc.right - rc.left, pt.y - rc.top, SWP_NOMOVE | SWP_NOZORDER); } }; return 0; } LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_CREATE : ::OnCreate(hWnd, uMsg, wParam, lParam); break; case WM_CLOSE : ::OnClose(hWnd, uMsg, wParam, lParam); break; case WM_NCDESTROY : ::OnNCDestroy(hWnd, uMsg, wParam, lParam); break; case WM_LBUTTONDOWN : ::OnLButtonDown(hWnd, uMsg, wParam, lParam); break; case WM_LBUTTONUP : ::OnLButtonUp(hWnd, uMsg, wParam, lParam); break; case WM_MOUSEMOVE : ::OnMouseMove(hWnd, uMsg, wParam, lParam); break; case WM_CANCELMODE : ::OnCancelMode(hWnd, uMsg, wParam, lParam); break; } return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hInstancePrev, LPSTR lpCmdLine, int nShowCmd) { const TCHAR tstrClassName[] = TEXT("test resize frame"); const TCHAR tstrTitleName[] = TEXT("title"); MSG msg; ::InitCommonControls(); //ウィンドウクラスの登録 ::Regist(tstrClassName, &::WndProc); //ウィンドウを作成して開く HWND hWnd = ::OpenWindow(tstrClassName, tstrTitleName, 800, 600, NULL); //ウィンドウの表示 ::ShowWindow(hWnd, SW_SHOW); //メッセージ回転 while(::GetMessage(&msg, NULL, 0, 0) == TRUE) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } //終了 return msg.wParam; }

noname#154655
質問者

お礼

出来ました。 マウスキャプチャーを使うとカーソル変更を自分で作らないといけないんですね。 てっきりマウスキャプチャーでも自動でカーソル変更出来ると思ってました。 これだったら自力で出来たと思うのですが、 「予期せぬ事態がおきるとWM_CANCELMODEが送られてくるので」ということなので、 聞いて良かったです。 カーソル変更はまだなのですが調べれば分かると思います。 何度も質問して申し訳ありませんでした。 ありがとうございます。

その他の回答 (4)

回答No.4

 こんにちは。度々すみません。  補足にウィンドウ移動からリサイズ~とあったので、リサイズ枠をクリックすると、ウィンドウを移動してからリサイズする様にしてしまったのですが、当方の解釈ミスだったかもしれません。  以下の3点を踏まえて改めて書き直します。  (1)リサイズ枠でマウスの移動量が指定した移動量に達してからサイズ変更する  (2)リサイズ枠を表示しないでサイズ変更を可能とする  (3)リサイズ枠をクリックした瞬間にウィンドウが移動する訳ではない #include<windows.h> #include<commctrl.h> #include<tchar.h> #pragma comment(lib, "comctl32.lib") const DWORD WS_EX_LAYERED = 0x80000; //ウィンドウ領域を固定する為に記憶する変数 static RECT s_rcKeep = {0}; //ウィンドウクラス登録 static ATOM Regist(LPCTSTR szClassName, WNDPROC wndProc) { WNDCLASSEX wndclass = {sizeof(wndclass)}; wndclass.hCursor = ::LoadCursor(NULL,IDC_ARROW); wndclass.hIcon = NULL; wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szClassName; wndclass.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH); wndclass.hInstance = ::GetModuleHandle(NULL); wndclass.style = 0; wndclass.lpfnWndProc = wndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; return ::RegisterClassEx(&wndclass); } //ウィンドウを作成して開く static HWND OpenWindow(LPCTSTR szClassName, LPCTSTR szTitleName, INT w, INT h, LPVOID pData) { HINSTANCE hInst = ::GetModuleHandle(NULL); HWND hWnd = ::CreateWindowEx(WS_EX_TOOLWINDOW | /*WS_EX_LAYERED |*/ WS_EX_ACCEPTFILES, szClassName, szTitleName, WS_POPUPWINDOW | WS_CLIPCHILDREN,// | WS_THICKFRAME, CW_USEDEFAULT,CW_USEDEFAULT, w, h, NULL, NULL, hInst, pData); return hWnd; } static LRESULT OnCreate(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return 0; } static LRESULT OnClose(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { ::DestroyWindow(hWnd); return 0; } static LRESULT OnNCDestroy(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { ::PostQuitMessage(0); return 0; } //リサイズ枠がクリックされた static LRESULT OnEnterSizeMove(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { //ウィンドウ領域を取る ::GetWindowRect(hWnd, &s_rcKeep); return 0; } //リサイズ枠が離された static LRESULT OnExitSizeMove(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { //リサイズ枠があったらスタイルを外す const DWORD dwStyle = ::GetWindowLong(hWnd, GWL_STYLE); if(dwStyle & WS_THICKFRAME) { ::SetWindowLong(hWnd, GWL_STYLE, dwStyle & ~WS_THICKFRAME); ::SetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); } return 0; } //リサイズ中 static LRESULT OnSizing(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LPRECT prc = (LPRECT)lParam; //移動量 LONG lPct = 16; //横に対して if(((prc->right - s_rcKeep.right) % lPct)) { //移動量に達さないのでs_rcKeepの値で固定 prc->right = s_rcKeep.right; } else { //移動量に達したのでs_rcKeepの値を更新 s_rcKeep.right = prc->right; } //縦に対して以下同様 if(((prc->bottom - s_rcKeep.bottom) % lPct)) { prc->bottom = s_rcKeep.bottom; } else { s_rcKeep.bottom = prc->bottom; } return 0; } //ヒットテスト static LRESULT OnHitTest(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { //リサイズ枠と見なす幅 const INT ResizeEdge = 4; POINT pt = {(short)LOWORD(lParam), (short)HIWORD(lParam)}; RECT rc; ::GetWindowRect(hWnd, &rc); //移動領域がクリックされた事にする if(pt.x <= rc.left + ResizeEdge || pt.y <= rc.top + ResizeEdge) return HTCAPTION; //クライアント領域がクリックされた事にする if(pt.x <= rc.right - ResizeEdge && pt.y <= rc.bottom - ResizeEdge) return HTCLIENT; //此処まで来たらリサイズ枠の範囲内にいる事にする //リサイズ枠のスタイルを入れる const DWORD dwStyle = ::GetWindowLong(hWnd, GWL_STYLE); ::SetWindowLong(hWnd, GWL_STYLE, dwStyle | WS_THICKFRAME); //右下へリサイズ領域がクリックされた事にする if(pt.x >= rc.right - ResizeEdge && pt.y >= rc.bottom - ResizeEdge) return HTBOTTOMRIGHT; //右へリサイズ領域がクリックされた事にする if(pt.x >= rc.right - ResizeEdge) return HTRIGHT; //下へリサイズ領域がクリックされた事にする if(pt.y >= rc.bottom - ResizeEdge) return HTBOTTOM; return HTNOWHERE; } LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_CREATE : ::OnCreate(hWnd, uMsg, wParam, lParam); break; case WM_CLOSE : ::OnClose(hWnd, uMsg, wParam, lParam); break; case WM_NCDESTROY : ::OnNCDestroy(hWnd, uMsg, wParam, lParam); break; case WM_ENTERSIZEMOVE: ::OnEnterSizeMove(hWnd, uMsg, wParam, lParam); break; case WM_EXITSIZEMOVE: ::OnExitSizeMove(hWnd, uMsg, wParam, lParam); break; case WM_SIZING : ::OnSizing(hWnd, uMsg, wParam, lParam); break; case WM_NCHITTEST : return ::OnHitTest(hWnd, uMsg, wParam, lParam); } return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hInstancePrev, LPSTR lpCmdLine, int nShowCmd) { const TCHAR tstrClassName[] = TEXT("test resize frame"); const TCHAR tstrTitleName[] = TEXT("title"); MSG msg; ::InitCommonControls(); //ウィンドウクラスの登録 ::Regist(tstrClassName, &::WndProc); //ウィンドウを作成して開く HWND hWnd = ::OpenWindow(tstrClassName, tstrTitleName, 800, 600, NULL); //ウィンドウの表示 ::ShowWindow(hWnd, SW_SHOW); //メッセージ回転 while(::GetMessage(&msg, NULL, 0, 0) == TRUE) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } //終了 return msg.wParam; }

noname#154655
質問者

お礼

リサイズ枠の非表示(スタイルの変更を繰り返す)は確認できました。 何度も答えて頂きありがとうございます。 一応マウスキャプチャーでもやってみようと思います。 また何か分からないことがあれば質問させて頂きたいと思います。 マウスキャプチャーの事で分からない所がある可能性もあるので、 念のためにマウスキャプチャーで確認後に質問を締め切らせて頂きます。 質問内容が違うのですが。 ちなみに、最初の補足で質問させて頂いた内容については、 OnEnterSizeMove()関数でミスをしてしまっていたので出来なかっただけでした。 ご迷惑をおかけしました。 すみませんでした。

noname#154655
質問者

補足

度々すみません。 マウスキャプチャーでやってみているのですが、 ソースを書いて頂いたものとどう違うのでしょうか? SetCapture()とReleaseCapture()を使用するみたいなのですが、 スタイルの変更を繰り返す方法と違うのでしょうか? マウスキャプチャーでまだ出来ていないので分からないのですが、 リサイズ中にでる枠は表示されないのでしょうか? もし、表示されないのであれば、 出来るだけマウスキャプチャーでやりたいので、 教えて頂ければ助かります。 最初質問する際に、リサイズ枠を表示しないでリサイズする方法と 書いておけば良かったのですが、 私の質問ミスでお手間を取らせてしまいすみません。

回答No.3

 こんばんは。すんません。  OnHitTest()関数の処理に間違いがあったので修正しました。ウィンドウ領域を取るAPIはGetClientRect()ではなくGetWindowRect()です。(複雑化して来ているので中々ぴっしりと成功させるのは困難です・・・)。 static LRESULT OnHitTest(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { //リサイズフレームを入れる const DWORD dwStyle = ::GetWindowLong(hWnd, GWL_STYLE); ::SetWindowLong(hWnd, GWL_STYLE, dwStyle | WS_THICKFRAME); POINT pt = {(short)LOWORD(lParam), (short)HIWORD(lParam)}; RECT rc; ::GetWindowRect(hWnd, &rc); //キャプション領域がクリックされた事にする //不用ならコメントアウトして下さい if(pt.x <= rc.left + 4 || pt.y <= rc.top + 4) return HTCAPTION; //右へリサイズ領域がクリックされた事にする if(pt.x >= rc.right - 4) return HTRIGHT; //下へリサイズ領域がクリックされた事にする if(pt.y >= rc.bottom - 4) return HTBOTTOM; //其れ以外はクライアント領域がクリックされた事にする return HTCLIENT; }

回答No.2

 こんばんは。補足頂きました。  遅れてしまってすんません。悪戦苦闘しておりました。移動の方は解決されたようですので、 ・サイズ変更枠の見た目が悪いので、表示しないようにする、又は分かりにくいようにすること  に関してですが、WS_THICKFRAMEのスタイルを無くした場合、リサイズ関連のメッセージが受け取れなくなる為、マウスのキャプチャーと言う芸当を使用するか、WM_NCHITTESTで巧みにスタイルの変更を繰り返せば、非表示のリサイズ枠処理が出来ます。  以下はクリックする度に、x,y座標が+10づつ加算されて移動する事と同時に、リサイズ枠無しで、リサイズ処理をしています。以下参考程度に。 #include<windows.h> #include<commctrl.h> #include<tchar.h> #pragma comment(lib, "comctl32.lib") const DWORD WS_EX_LAYERED = 0x80000; //移動量 static POINT s_ptMoved = {10, 10}; //確保 static RECT s_rcKeep = {0}; //ウィンドウクラス登録 static ATOM Regist(LPCTSTR szClassName, WNDPROC wndProc) { WNDCLASSEX wndclass = {sizeof(wndclass)}; wndclass.hCursor = ::LoadCursor(NULL,IDC_ARROW); wndclass.hIcon = NULL; wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szClassName; wndclass.hbrBackground = (HBRUSH)::GetStockObject(WHITE_BRUSH); wndclass.hInstance = ::GetModuleHandle(NULL); wndclass.style = 0; wndclass.lpfnWndProc = wndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; return ::RegisterClassEx(&wndclass); } //ウィンドウを作成して開く static HWND OpenWindow(LPCTSTR szClassName, LPCTSTR szTitleName, INT w, INT h, LPVOID pData) { HINSTANCE hInst = ::GetModuleHandle(NULL); HWND hWnd = ::CreateWindowEx(WS_EX_TOOLWINDOW | /*WS_EX_LAYERED |*/ WS_EX_ACCEPTFILES, szClassName, szTitleName, WS_POPUPWINDOW | WS_CLIPCHILDREN,// | WS_THICKFRAME, CW_USEDEFAULT,CW_USEDEFAULT, w, h, NULL, NULL, hInst, pData); return hWnd; } static LRESULT OnCreate(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return 0; } static LRESULT OnClose(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { ::DestroyWindow(hWnd); return 0; } static LRESULT OnNCDestroy(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { ::PostQuitMessage(0); return 0; } static LRESULT OnEnterSizeMove(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { //ウィンドウ領域を取る ::GetWindowRect(hWnd, &s_rcKeep); //移動量を加算する s_rcKeep.left += s_ptMoved.x; s_rcKeep.top += s_ptMoved.y; //リサイズ無しで加算する ::SetWindowPos(hWnd, NULL, s_rcKeep.left, s_rcKeep.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER); //移動後のウィンドウ領域を取る ::GetWindowRect(hWnd, &s_rcKeep); return 0; } //マウスボタンが離された時に送られる static LRESULT OnExitSizeMove(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { //リサイズ枠を無くす const DWORD dwStyle = ::GetWindowLong(hWnd, GWL_STYLE); ::SetWindowLong(hWnd, GWL_STYLE, dwStyle & ~WS_THICKFRAME); ::SetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); return 0; } static LRESULT OnSizing(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { LPRECT prc = (LPRECT)lParam; //移動量 LONG lPct = 16; //x, yのドラッグ位置を合わせる prc->left = s_rcKeep.left; prc->top = s_rcKeep.top; //横に対して if(((prc->right - s_rcKeep.right) % lPct)) { //移動量に達さないのでs_rcKeepの値で固定 prc->right = s_rcKeep.right; } else { //移動量に達したのでs_rcKeepの値を更新 s_rcKeep.right = prc->right; } //縦に対して以下同様 if(((prc->bottom - s_rcKeep.bottom) % lPct)) { prc->bottom = s_rcKeep.bottom; } else { s_rcKeep.bottom = prc->bottom; } return 0; } static LRESULT OnHitTest(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { //リサイズ枠を入れるが、表示はされない const DWORD dwStyle = ::GetWindowLong(hWnd, GWL_STYLE); ::SetWindowLong(hWnd, GWL_STYLE, dwStyle | WS_THICKFRAME); POINT pt = {(short)LOWORD(lParam), (short)HIWORD(lParam)}; RECT rc; ::GetClientRect(hWnd, &rc); if(pt.x > rc.right - 4) return HTRIGHT; if(pt.y > rc.bottom - 4) return HTBOTTOM; return HTCLIENT; } LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_CREATE : ::OnCreate(hWnd, uMsg, wParam, lParam); break; case WM_CLOSE : ::OnClose(hWnd, uMsg, wParam, lParam); break; case WM_NCDESTROY : ::OnNCDestroy(hWnd, uMsg, wParam, lParam); break; case WM_ENTERSIZEMOVE : ::OnEnterSizeMove(hWnd, uMsg, wParam, lParam); break; case WM_EXITSIZEMOVE : ::OnExitSizeMove(hWnd, uMsg, wParam, lParam); break; case WM_SIZING : ::OnSizing(hWnd, uMsg, wParam, lParam); break; case WM_NCHITTEST : return ::OnHitTest(hWnd, uMsg, wParam, lParam); } return ::DefWindowProc(hWnd, uMsg, wParam, lParam); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hInstancePrev, LPSTR lpCmdLine, int nShowCmd) { const TCHAR tstrClassName[] = TEXT("test resize frame"); const TCHAR tstrTitleName[] = TEXT("title"); MSG msg; ::InitCommonControls(); //ウィンドウクラスの登録 ::Regist(tstrClassName, &::WndProc); //ウィンドウを作成して開く HWND hWnd = ::OpenWindow(tstrClassName, tstrTitleName, 800, 600, NULL); //ウィンドウの表示 ::ShowWindow(hWnd, SW_SHOW); //メッセージ回転 while(::GetMessage(&msg, NULL, 0, 0) == TRUE) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } //終了 return msg.wParam; }

回答No.1

 こんばんは。  其の侭WS_THICKFRAMEを付加してから、WM_ENTERSIZEMOVEで初回ドラッグとしてウィンドウ矩形領域を記憶、WM_SIZINGで移動量の制限をかけて見ては如何でしょう。以下参考程度に。 //固定ウィンドウ領域を記憶する為の変数 static RECT s_rcKeep = {0}; //ウィンドウ枠が初めてドラッグされた時に1回だけ呼ばれる static LRESULT OnEnterSizeMove(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { //ウィンドウ枠を含めた矩形領域を記憶 ::GetWindowRect(hWnd, &s_rcKeep); return 0; } //ウィンドウ枠をドラッグしている間、リアルタイムで送られてくる static LRESULT OnSizing(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { //lParamにはドラッグされているスクリーン領域が入っている LPRECT prc = (LPRECT)lParam; //移動量(16ピクセル動くごとに16ピクセル分幅が広がる) LONG lPct = 16; //横に対して if(((prc->right - s_rcKeep.right) % lPct)) { //移動量に達さないのでs_rcKeepの値で固定 prc->right = s_rcKeep.right; } else { //移動量に達したのでs_rcKeepの値を更新 s_rcKeep.right = prc->right; } //縦に対して以下同様 if(((prc->bottom - s_rcKeep.bottom) % lPct)) { prc->bottom = s_rcKeep.bottom; } else { s_rcKeep.bottom = prc->bottom; } return 0; } LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_ENTERSIZEMOVE : ::OnEnterSizeMove(hWnd, uMsg, wParam, lParam); break; case WM_SIZING : ::OnSizing(hWnd, uMsg, wParam, lParam); break; } return ::DefWindowProc(hWnd, uMsg, wParam, lParam); }

noname#154655
質問者

お礼

出来ました。 私のミスで出来なかっただけでした。 すみません。 もし良ければでいいので、サイズ変更枠を表示しないようにする、 又は、分かりにくいようにすることは出来るのでしょうか? もちろん、今のままサイズ変更が出来る状態のままです。 何度も質問して申し訳ありません。

noname#154655
質問者

補足

一応出来たのですが、 ウィンドウを移動してサイズ変更しようとすると、 右下の座標が移動する前の座標のままなので、 クリックしてもサイズ変更しなかった場合に、 右下がそこの座標のままになってしまうのですが、 どうすればいいのでしょうか? それと、これはこういうことが出来たら良いなという事なので 答えて頂かなくても良いです。 サイズ変更枠の見た目が悪いので、 表示しないようにする、又は分かりにくいようにすることは出来るのでしょうか?

関連するQ&A

  • ウィンドウのサイズ変更について

    タイトルバーがないウィンドウのサイズ変更について質問です。 タイトルバーがあるウィンドウでは、 ウィンドウの端にマウスカーソルを合わせると サイズ変更のカーソルに変わってサイズ変更が出来ますけど、 タイトルバーがないウィンドウでは出来ないのですが、 どうすればサイズ変更が出来るようになるのでしょうか? CreateWindowEx()には、 拡張ウィンドウスタイルには、 WS_EX_TOOLWINDOW | WS_EX_LAYERED | WS_EX_ACCEPTFILES ウィンドウスタイルには、 WS_POPUPWINDOW | WS_BORDER を渡しています。 開発環境 XP Visual Studio 2005 C、C++

  • ウィンドウスタイルの変更

    現象を文章で書きます。 まず始めに、ウィンドウスタイルにWS_BORDER | WS_CHILD | WS_VISIBLE | WS_THICKFRAME(サイズ変更境界を持つウィンドウ)を設定したボタンを作りました。 それを後の処理で style = GetWindowLongPtr(hWnd,GWL_STYLE); //ウィンドウスタイルの取得 style ^= WS_THICKFRAME; //style XOR WS_THICKFRAMESetWindowLongPtr(hWnd,GWL_STYLE,style); //新しいウィンドウスタイルを設定 としたらボタンのサイズ変更は出来なくなるのですが、 サイズ変更境界が表示されたままになります。 その状態でウィンドウを最小化、元に戻すとするとサイズ変更境界だけ消えたような変な形のボタンになります。 これがどうしてもいやなのです。 原因もわかりません。 対処法を教えてもらえないでしょうか? 環境はBorlandです。

  • ウインドウスタイルの、WS_EX_TOPMOST

    引き続きVC++2008でWindowsフォームアプリケーションを作っています。 WindowsAPIでのウインドウ製作中です。 今Form1を親とするウインドウで、CreateWindowEx内のウインドウスタイルの個所の引数にWS_EX_TOPMOSTを指定したのですが どうも最前面に表示されてくれないようです。 これは何か他にやらないといけない事があるのでしょうか? なお、CreateWindowEx関数は現在、最初の引数を WS_EX_TOOLWINDOW にして、WS_EX_TOPMOST以外のウインドウスタイルは WS_SYSMENU | WS_VSCROLL | WS_SIZEBOX がある状態です。

  • WindowsAPIの、ウインドウの表示非表示

    WindowsAPIのCreateWindowEx関数で作った 例えば第一引数が WS_EX_TOOLWINDOW|WS_EX_TOPMOST で第四引数が WS_SYSMENU | WS_VSCROLL | WS_SIZEBOX のウインドウを、何かのアクションがあったときいったん非表示にしてから、また何かのアクションがあった時に表示させるには、どのような物を使うのがベストなのでしょうか? プロシージャ内(HWNDはhw)で一例として(…?)試しに以下だけのものでやってみると long lStyle = GetWindowLong(hw, GWL_STYLE); lStyle = ~WS_VISIBLE; SetWindowLong(hw, GWL_STYLE, lStyle); 確かに非表示扱いにはなるようなのですが、これだけではスクリーンは再描画されず、再描画されるには人為的に別ウインドウを移動したりしないといけません。 おそらく「何かによって再描画させられれば」出来ると思うのですが それはどうすれば実現できるのでしょうか? また、これより もっと「こっちの方がいい」といった方法はありますでしょうか?

  • タスクマネージャに表示するダイアログの変更

    開発環境: Visual Studio 2008 Pro 現在メインウィンドウのOnInitDialog()内から複数のダイアログを順次モーダル表示させ、 OnInitDialog()を抜ける時には自身のウィンドウに対してWM_CLOSEを送ることでアプリを 終了させるプログラムを作成しております。 ですがこのやり方だと、モーダル画面等で処理中にはタスクマネージャーにアプリケーションが 表示されません。 特定のダイアログに対してウィンドウスタイルを変更すれば解決できるかと思い、 (1)メインウィンドウのOnInitDialog()開始直後に自身のウィンドウスタイルからWS_EX_APPWINDOWを削除。 (2)代わりにメインウィンドウとして認識させたいダイアログに対してWS_EX_APPWINDOWを設定。 上記の処理を試してみましたが、タスクマネージャーに表示させることができませんでした。 必要な処理などに誤りがあるのでしょうか? もしご存知の方がいらっしゃいましたらどうかご教示いただけます様お願い致します。

  • C# Windowsでのユーザー名変更

    C#を使用してWindowsのユーザーアカウントの名前を変更したいのですが、なかなか方法がみつかりません。 どなたかご教示願います。 環境:WinXP,Visual Studio 2005

  • ちらつきについて

    ウィンドウとボタンのちらつきについて質問です。 以前質問させて頂いた http://okwave.jp/qa5097510.html をして、更新は速くなったのですが、 ちらつきがあるのですが、原因が分かりません。 順番としては、 ーーーーーーーーーーーーーーーーー SendMessage()で再描画阻止 ボタンの移動 ウィンドウのサイズ変更 SendMessage()で再描画阻止を解除 ボタンの再描画 ウィンドウの再描画 ーーーーーーーーーーーーーーーーー です。 色々試してみて現在はこの順番で処理をしています。 他の所に問題があるのかもしれませんが。 どうすれば、ちらつきが出ないようにできるのでしょうか? 開発環境 XP Visual Studio 2005 C、C++でWindowsAPIを使用しています。

  • Windowsでウィンドウのサイズ変更をしたいのですが…

    Windowsでウィンドウのサイズ変更をしたいのですがサイズが通常変更できないウィンドウでもサイズ変更ができ、サイズを変更してもウィンドウ内で隠れる部分などがなく縮小した感じで表示できるツール又は方法はありませんか?

  • Visual Studioのようなウィンドウ管理

    Visual Studio 2012 ExpressでC#を使って開発しています。Visual Studio 2012 Expressが採用しているものと同じようにウィンドウ間のドッキングや閉じる、折りたたむといった操作が行える機能を自分のソフトにも組み込みたいのですが、何かライブラリがあるのでしょうか? Visual Studio 2012 Express以外のソフトウェアでも同様の操作感を持つものを知っているので、どこかが開発したライブラリか何かではないかと思うのですが…。

  • windows2000でC++の環境を整えたいと思っています。

    windows2000でC++の環境を整えたいと思っています。 使用するアプリケーションの都合上、windows2000を使わざるを得ない状況です。 C++の環境を整えようと思いvisual studio2008をインストールしようとしたら windows2000にはインストールできないとのことでした。 この場合、新たにvisual studio2005を買うなどしなければC++をインストールすることは 不可能ということでしょうか。 他に方法がありましたら教えてください。よろしくお願いします。 (パソコンを買い換えるということも考えておりますが、windows2000で使えるようになると一番嬉しいです!)

専門家に質問してみよう