4

ウィンドウがあり、他のウィンドウと同様に、境界線のサイズを変更するように境界線を実装したいと考えています。コメントと回答からの提案を取り入れて、コードを書き直しました。WM_GETMINMAXINFO の場合:

MINMAXINFO *min_max = reinterpret_cast<MINMAXINFO *>(lparam);

min_max->ptMinTrackSize.x = MINX;
min_max->ptMinTrackSize.y = MINY;

MINX と MINY は、ウィンドウの最小サイズです。WM_NCHITTEST の場合:

RECT wnd_rect;
int x, y;

GetWindowRect (window, &wnd_rect);
x = GET_X_LPARAM (lparam) - wnd_rect.left;
y = GET_Y_LPARAM (lparam) - wnd_rect.top;

if (x >= BORDERWIDTH && x <= wnd_rect.right - wnd_rect.left - >BORDERWIDTH && y >= BORDERWIDTH && y <= TITLEBARWIDTH)
    return HTCAPTION;

else if (x < BORDERWIDTH && y < BORDERWIDTH)
    return HTTOPLEFT;
else if (x > wnd_rect.right - wnd_rect.left - BORDERWIDTH && y < BORDERWIDTH)
    return HTTOPRIGHT;
else if (x > wnd_rect.right - wnd_rect.left - BORDERWIDTH && y > wnd_rect.bottom - wnd_rect.top - BORDERWIDTH)
    return HTBOTTOMRIGHT;
else if (x < BORDERWIDTH && y > wnd_rect.bottom - wnd_rect.top - BORDERWIDTH)
    return HTBOTTOMLEFT;

else if (x < BORDERWIDTH)
    return HTLEFT;
else if (y < BORDERWIDTH)
    return HTTOP;
else if (x > wnd_rect.right - wnd_rect.left - BORDERWIDTH)
    return HTRIGHT;
else if (y > wnd_rect.bottom - wnd_rect.top - BORDERWIDTH)
    return HTBOTTOM;

return HTCLIENT;

変数は一目瞭然です。このコードは、ドラッグしてウィンドウのサイズを変更できる境界線を提供します。右下、下、右の境界線をドラッグするとうまくいきます。他の境界線をドラッグしようとすると、ウィンドウの右下隅がまだ前後に動いているように見えます。これは、Google Chrome または Visual Studio 2012 で同じ境界線のセットで表示されるものと似ていますが、Windows エクスプローラーでは表示されません。

Windows エクスプローラーのように、上または左の境界線のサイズを変更しているときに、右下隅が前後に「くねくね」しないようにする方法はありますか?

4

5 に答える 5

2

残念ながら、これはあなたが待っている答えではありません。Windows 7 では、WS_POPUP スタイルのトップレベル ウィンドウを同時に移動およびサイズ変更すると、実際には機能しません。視覚的には、ウィンドウが最初に移動され、その後サイズが変更されます。左または上でサイズを変更すると、移動操作によって背景のピクセルが一時的に表示され、ユーザー エクスペリエンスが非常に悪くなります。

何が起こっているかを理解している限り、WM_GETMINMAXINFO または WM_NCCALCSIZE とは何の関係もありません。

効果を確認するのは非常に簡単です。ほとんど空のウィンドウ プロシージャを使用して WS_VISIBLE ウィンドウを開き、タイマーを設定し、WM_TIMER で SetWindowPos を使用して、ウィンドウのサイズを大きくしながらウィンドウを少し左に移動し、右端を同じ場所に配置します。背景ピクセルが表示されますが、これはばかげています。Windows XP ではそのような破損はありません。

私は多くのトリックを試しましたが、それらのいくつかは非常にねじれていましたが、最終結果は常に同じです: ウィンドウが最終的に新しい状態でレンダリングされた瞬間、最初に移動操作があり、次にサイズが 1 です...

2 つのオプションが残されています (Seven+ をターゲットにする場合):

1) 標準サイズの境界線を使用し、新しい API (例: DwmExtendFrameIntoClientArea) を利用して、フレームをニーズに合わせてカスタマイズします。http://msdn.microsoft.com/en-us/library/windows/desktop/bb688195.aspxで DWM を使用したカスタム ウィンドウ フレームを参照してください。

2) WS_POPUP を使用せずに WS_BORDER を使用し、Windows をだまして境界線をレンダリングしないようにするトリックを使用します。それがVS2012がやっていることのようです。

忘れないでください。ウィンドウの内側でちらつくことは別の話です。ここでは、右/下端の「安定性」について話しているだけです。

于 2013-10-09T10:36:25.770 に答える