ウィンドウのサイズ変更について質問です。
ウィンドウをサイズ変更する際に、マウスで指定数動いた時だけ
サイズ変更するようにしたいのですが、何か方法はあるのでしょうか?
ちなみに、
拡張ウィンドウスタイルは、
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で質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) 【マクロ】スクショ印刷がうまく動かない件 5 2022/12/06 17:37
- オープンソース Python openpyxlを使用したセル番地の使用について 1 2023/08/03 22:05
- その他(OS) Windowsで大量の画像サイズを半自動で変更する方法 6 2023/02/17 08:45
- モニター・ディスプレイ パソコンでスクリーンショットしたもの(HP)を印刷しました。 3 2022/07/03 16:39
- Excel(エクセル) 【VBA】 Alt+PrintScreenにてアクティブウィンドウのスクショを貼付する方法 4 2022/12/08 20:53
- Word(ワード) Microsoft Word2023で、修正箇所を表示させたい 1 2023/02/09 10:07
- Visual Basic(VBA) エクセルのマクロについて教えてください。 3 2023/02/22 08:53
- Chrome(クローム) (win10)ショートカットの開き方について 1 2023/02/19 18:55
- Visual Basic(VBA) 【ご教示ください】VBAの記述方法がわかりません。 2 2022/08/12 21:28
- Visual Basic(VBA) コマンドプロンプトでフォルダ内(デスクトップ)の複数PDFファイルの1ページ目だけを印刷したい 1 2022/09/11 23:33
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
- ・お風呂の温度、何℃にしてますか?
- ・とっておきの「まかない飯」を教えて下さい!
- ・2024年のうちにやっておきたいこと、ここで宣言しませんか?
- ・いけず言葉しりとり
- ・土曜の昼、学校帰りの昼メシの思い出
- ・忘れられない激○○料理
- ・あなたにとってのゴールデンタイムはいつですか?
- ・とっておきの「夜食」教えて下さい
- ・これまでで一番「情けなかったとき」はいつですか?
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エディットコントロール入力時...
-
プログラミングでエラーが出ま...
-
エディットボックスの背景の色...
-
エラー Run-Time Check Failur...
-
音量調節
-
Win32APIでウィンドウを中央に...
-
1~1000,1001~2000の間に素数が...
-
c言語のプログラミングでキーボ...
-
オーバーレイみたいな処理がしたい
-
「指定されたキャストは有効で...
-
DWORDの実際の型は何でしょうか
-
プログラムでの数字につく”f”の...
-
プログラミング初心者です。 Py...
-
信頼区間の1.96や1.65ってどこ...
-
C言語での引数の省略方法
-
20'(角度)の計算がわかりま...
-
エクセルで可視セルにのみ値貼...
-
「Aに対するBの割合」と「Aに対...
-
Enterキーを押されたら次の処理...
-
ある商品のロス率を5%見込み、...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
音量調節
-
エラー Run-Time Check Failur...
-
Win32APIでウィンドウを中央に...
-
return文がない場合の戻り値は...
-
1~1000,1001~2000の間に素数が...
-
ダイアログプログラムでEnterキ...
-
ボタンの色(WINAPI)
-
C言語win32api、エディットボッ...
-
MessageBoxについて
-
プログラミングでエラーが出ま...
-
キャレットの現在位置の表示 (W...
-
エディットボックスの背景の色...
-
エディットコントロール入力時...
-
オーバーレイみたいな処理がしたい
-
ウィンドウのサイズ変更について
-
C#のswitch文を簡略化したいの...
-
猫でもわかるWindowsプログラミ...
-
WM_INITDIALOGのフック
-
MoveToExとLineToについて
-
【Windowsアプリ】ファイルのド...
おすすめ情報