0

このコントロールでなんとか長方形を描くことができましたが、2つの問題があります。1つは、フォルダの選択ダイアログをマウスで動かした後、白い長方形が表示されることです。ここでの問題は、正しいメッセージに接続することです。ダイアログウィンドウの作成時に発生するWM_ERASEBKGNDを選択しましたが、効果はありません。前に表示されていないコントロールの一部が画面に戻ったときに呼び出す必要があるため、ウィンドウを端にドラッグして、コントロールが表示されず、ドラッグして戻すと、白い長方形が表示されます。しかし、2番目の問題が発生します。コントロールのテキストについても説明します。

だからここに私の試みがあります、何かアイデアはありますか?

#include <windows.h>
#include <shlobj.h>

WNDPROC origStaticProc;
LRESULT CALLBACK myStaticProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
  switch (uMsg) {
    case WM_ERASEBKGND: {
      HDC dc = GetDC(hWnd);
      RECT clientRect;
      GetClientRect(hWnd,&clientRect);
      FillRect(dc, &clientRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
      ReleaseDC(hWnd, dc);
      break;
    }
  }
  return CallWindowProc(origStaticProc, hWnd, uMsg, wParam, lParam );
}

int CALLBACK BrowseCallBackProc( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) {
  switch(uMsg) {
    case BFFM_INITIALIZED: {
      HWND static_control = NULL;
      char szClassName[_MAX_PATH];
      for (HWND hChild = GetWindow(hwnd, GW_CHILD); hChild != NULL; hChild =  GetNextWindow(hChild, GW_HWNDNEXT))
      {
        if ((GetWindowLong(hChild, GWL_STYLE) & WS_VISIBLE) == 0) continue;
        GetClassName(hChild, szClassName, _countof(szClassName));
        if (!strcmp("Static",szClassName)) {
          static_control = hChild;
          break;
        }
      }
      HFONT hFont = CreateFont (13, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Fixedsys"));
      SendMessage(static_control, WM_SETFONT, (WPARAM)hFont, TRUE);
      origStaticProc = ( WNDPROC ) SetWindowLongW( static_control, GWL_WNDPROC,( LONG ) myStaticProc );
      break;
    }
  }
}

int main() {
  using namespace std;
  BROWSEINFOW bi;
  LPITEMIDLIST pidl;
  LPMALLOC pMalloc;
  if (SUCCEEDED (::SHGetMalloc (&pMalloc))) {
    ::ZeroMemory (&bi,sizeof(bi));  
    bi.hwndOwner = NULL;
    bi.lpszTitle = L"I should be visible on a white background. Now you must drag me to edge of the screen and back.";
    bi.pszDisplayName = 0;
    bi.pidlRoot = 0;
    bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_VALIDATE | BIF_USENEWUI | BIF_UAHINT;
    bi.lpfn = BrowseCallBackProc;
    bi.lParam = (LPARAM)L"d:\\";
    pidl = ::SHBrowseForFolderW(&bi);
  }
}

それはどのように見えるか:

それはどのように見えるか

もちろんそれはどうあるべきか:

もちろんどうあるべきか

4

1 に答える 1

0

とった。問題は、SHBrowseForFolder に使用されるコールバック関数がウィンドウ自体のコールバックと異なることを知らなかったことです。ダイアログをサブクラス化するには、別の関数を実行する必要があることがわかりました。

これは醜くて安全でないコードですが、コンパイルして原理を示しています。

#include <windows.h>
#include <shlobj.h>

WNDPROC origBffProc;
LRESULT CALLBACK bffProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
  static HBRUSH hBrush = (HBRUSH)GetStockObject(HOLLOW_BRUSH);
  switch (uMsg) {
    case WM_CTLCOLORSTATIC: {
      HDC hdcStatic = (HDC) wParam;
      SetTextColor(hdcStatic, RGB(255,0,0));
      SetBkColor(hdcStatic, RGB(255,255,0));
      return (INT_PTR)hBrush;
    }
  }
  return CallWindowProc(origBffProc, hWnd, uMsg, wParam, lParam );
}

int CALLBACK BrowseCallBackProc( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) {
  switch(uMsg) {
    case BFFM_INITIALIZED: {
      HWND static_control = NULL;
      char szClassName[_MAX_PATH];
      for (HWND hChild = GetWindow(hwnd, GW_CHILD); hChild != NULL; hChild =  GetNextWindow(hChild, GW_HWNDNEXT))
      {
        if ((GetWindowLong(hChild, GWL_STYLE) & WS_VISIBLE) == 0) continue;
        GetClassName(hChild, szClassName, _countof(szClassName));
        if (!strcmp("Static",szClassName)) {
          static_control = hChild;
          break;
        }
      }
      HFONT hFont = CreateFont (13, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Fixedsys"));
      PostMessage(static_control, WM_SETFONT, (WPARAM)hFont, TRUE);
      origBffProc = ( WNDPROC ) SetWindowLongW( hwnd, GWL_WNDPROC,( LONG ) bffProc );
      break;
    }
  }
}
int main() {
  using namespace std;
  BROWSEINFOW bi;
  LPITEMIDLIST pidl;
  LPMALLOC pMalloc;
  if (SUCCEEDED (::SHGetMalloc (&pMalloc))) {
    ::ZeroMemory (&bi,sizeof(bi));  
    bi.hwndOwner = NULL;
    bi.lpszTitle = L"You are about to erase a directory, be careful! (and don't blame me)";
    bi.pszDisplayName = 0;
    bi.pidlRoot = 0;
    bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_VALIDATE | BIF_USENEWUI | BIF_UAHINT;
    bi.lpfn = BrowseCallBackProc;
    bi.lParam = (LPARAM)L"d:\\";
    pidl = ::SHBrowseForFolderW(&bi);
  }
}
于 2013-02-05T23:28:18.477 に答える