ウィンドウのサイズ変更について質問です。
ウィンドウをサイズ変更する際に、マウスで指定数動いた時だけ
サイズ変更するようにしたいのですが、何か方法はあるのでしょうか?
ちなみに、
拡張ウィンドウスタイルは、
WS_EX_TOOLWINDOW | WS_EX_LAYERED | WS_EX_ACCEPTFILES
ウィンドウスタイルは、
WS_POPUPWINDOW | WS_CLIPCHILDREN
です。
「WS_THICKFRAME」を使用してやろうとしたのですが出来ませんでした。
何か方法があるのかもしれませんが。
開発環境
XP
Visual Studio 2005
C、C++でWindowsAPIを使用しています。
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;
}
出来ました。
マウスキャプチャーを使うとカーソル変更を自分で作らないといけないんですね。
てっきりマウスキャプチャーでも自動でカーソル変更出来ると思ってました。
これだったら自力で出来たと思うのですが、
「予期せぬ事態がおきるとWM_CANCELMODEが送られてくるので」ということなので、
聞いて良かったです。
カーソル変更はまだなのですが調べれば分かると思います。
何度も質問して申し訳ありませんでした。
ありがとうございます。
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;
}
この回答への補足
度々すみません。
マウスキャプチャーでやってみているのですが、
ソースを書いて頂いたものとどう違うのでしょうか?
SetCapture()とReleaseCapture()を使用するみたいなのですが、
スタイルの変更を繰り返す方法と違うのでしょうか?
マウスキャプチャーでまだ出来ていないので分からないのですが、
リサイズ中にでる枠は表示されないのでしょうか?
もし、表示されないのであれば、
出来るだけマウスキャプチャーでやりたいので、
教えて頂ければ助かります。
最初質問する際に、リサイズ枠を表示しないでリサイズする方法と
書いておけば良かったのですが、
私の質問ミスでお手間を取らせてしまいすみません。
リサイズ枠の非表示(スタイルの変更を繰り返す)は確認できました。
何度も答えて頂きありがとうございます。
一応マウスキャプチャーでもやってみようと思います。
また何か分からないことがあれば質問させて頂きたいと思います。
マウスキャプチャーの事で分からない所がある可能性もあるので、
念のためにマウスキャプチャーで確認後に質問を締め切らせて頂きます。
質問内容が違うのですが。
ちなみに、最初の補足で質問させて頂いた内容については、
OnEnterSizeMove()関数でミスをしてしまっていたので出来なかっただけでした。
ご迷惑をおかけしました。
すみませんでした。
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);
}
この回答への補足
一応出来たのですが、
ウィンドウを移動してサイズ変更しようとすると、
右下の座標が移動する前の座標のままなので、
クリックしてもサイズ変更しなかった場合に、
右下がそこの座標のままになってしまうのですが、
どうすればいいのでしょうか?
それと、これはこういうことが出来たら良いなという事なので
答えて頂かなくても良いです。
サイズ変更枠の見た目が悪いので、
表示しないようにする、又は分かりにくいようにすることは出来るのでしょうか?
出来ました。
私のミスで出来なかっただけでした。
すみません。
もし良ければでいいので、サイズ変更枠を表示しないようにする、
又は、分かりにくいようにすることは出来るのでしょうか?
もちろん、今のままサイズ変更が出来る状態のままです。
何度も質問して申し訳ありません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ウィンドウ非表示に時に表示し...
-
ボタンの色(WINAPI)
-
ウィンドウのサイズ変更について
-
LoadImageを使用し、タイトルバ...
-
ダイアログプログラムでEnterキ...
-
return文がない場合の戻り値は...
-
不明なエラー
-
Enterキーを押されたら次の処理...
-
信頼区間の1.96や1.65ってどこ...
-
C言語での引数の省略方法
-
DWORDの実際の型は何でしょうか
-
マイナスからプラスへ転じた時...
-
複数桁10進数の*桁目だけを抽出...
-
構文エラー";"が型の前にあり...
-
「指定されたキャストは有効で...
-
Aの値からBの値を除するとは??
-
C言語を実行すると-infが出てき...
-
プログラムでの数字につく”f”の...
-
ある商品のロス率を5%見込み、...
-
「Aに対するBの割合」と「Aに対...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
音量調節
-
エラー Run-Time Check Failur...
-
Win32APIでウィンドウを中央に...
-
return文がない場合の戻り値は...
-
1~1000,1001~2000の間に素数が...
-
ダイアログプログラムでEnterキ...
-
ボタンの色(WINAPI)
-
MessageBoxについて
-
C言語win32api、エディットボッ...
-
エディットボックスの背景の色...
-
キャレットの現在位置の表示 (W...
-
プログラミングでエラーが出ま...
-
オーバーレイみたいな処理がしたい
-
エディットコントロール入力時...
-
ウィンドウのサイズ変更について
-
C#のswitch文を簡略化したいの...
-
猫でもわかるWindowsプログラミ...
-
WM_INITDIALOGのフック
-
MoveToExとLineToについて
-
COMPORTマルチスレッドで例外発生
おすすめ情報