C++ アプリで、CreateWindowEx を使用してボタンを作成し、後で SetWindowPos を使用してその位置を変更しようとしましたが、必要な場所にボタンが表示されません。
興味深いのは、ウィンドウのサイズを変更すると(プログラムではなくマウスで)、ボタンが表示されるはずのボタンと同じサイズの空白のシルエットが一瞬表示されることです。これは、ウィンドウのサイズ変更イベントに応答して SetWindowPos も呼び出すためです。ただし、実際のボタンは同じ場所にあります。スクリーンショットを投稿したいのですが、何らかの理由でシルエットがスクリーンショットに表示されません。
これは、X 位置を変更するコードです (Y 位置を変更するコードはほとんど同じです)。
HRESULT Control::put_Left(float left)
{
RECT windowRect;
::GetWindowRect(m_hWnd, &windowRect);
if (m_isTopLevel)
{
BOOL bResult = ::SetWindowPos(
m_hWnd,
nullptr,
static_cast<int>(DesktopDpi::GetInstance().DipsToPixelsX(left)),
windowRect.top,
0,
0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOREPOSITION
);
if (!bResult)
return HRESULT_FROM_WIN32(::GetLastError());
}
else
{
// NOTE: for a button this is the code that will execute, because a
// button is not a top-level window
HWND hWndParent = ::GetParent(m_hWnd);
if (hWndParent == nullptr)
return HRESULT_FROM_WIN32(::GetLastError());
POINT parentPos = {0, 0};
if (!::ClientToScreen(hWndParent, &parentPos))
return E_FAIL;
BOOL bResult = ::SetWindowPos(
m_hWnd,
nullptr,
static_cast<int>(DesktopDpi::GetInstance().DipsToPixelsX(left)),
windowRect.top - parentPos.y,
0,
0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOREPOSITION
);
if (!bResult)
return HRESULT_FROM_WIN32(::GetLastError());
}
return S_OK;
}