0

角の丸い編集ボックスを作成したいのですが、長方形の編集ボックスを描画するため、標準の編集ボックス コントロールを使用できません。

それを行う方法についての提案や指針はありますか?

4

1 に答える 1

3

いくつかのオプションがあります:-

  1. 親コントロールを作成し、その中に子のフチなしテキスト編集コントロールを配置します
  2. テキスト編集コントロールをサブクラス化し、NC_PAINTをオーバーロードして境界線を描画します

アップデート

サンプルプログラムをいじった後、サブクラス化された編集コントロールが実際には機能しないことに徐々に気づき、オンラインでこれを確認しました(一貫性を保ってくれてありがとうMS!)。

つまり、オプション1とオプション3を残すだけです(考えてみてください)。

  1. 独自の編集コントロールを作成する

方法1の例を次に示します。

#include <windows.h>

LRESULT __stdcall EditboxProc (HWND window, unsigned message, WPARAM w_param, LPARAM l_param)
{
  bool
    use_default = true;

  LRESULT
    result = 0;

  switch (message)
  {
  case WM_CREATE:
    {
      RECT
        client;

      GetClientRect (window, &client);

      HWND
        edit = CreateWindowEx (0,
                               TEXT ("Edit"),
                               0,
                               WS_VISIBLE | WS_CHILD,
                               10,
                               10,
                               client.right - 20,
                               client.bottom - 20,
                               window,
                               0,
                               GetModuleHandle (0),
                               0);

      SetWindowLongPtr (window, GWLP_USERDATA, static_cast <LONG> (reinterpret_cast <LONG_PTR> (edit)));
    }
    break;

  case WM_SIZE:
    {
      RECT
        client;

      GetClientRect (window, &client);
      SetWindowPos (reinterpret_cast <HWND> (static_cast <LONG_PTR> (GetWindowLongPtr (window, GWLP_USERDATA))), 0, 10, 10, client.right - 20, client.bottom - 20, SWP_NOZORDER | SWP_NOOWNERZORDER);

      use_default = false;
    }
    break;
  }

  return use_default ? DefWindowProc (window, message, w_param, l_param) : result;
}

LRESULT __stdcall WindowProc (HWND window, unsigned message, WPARAM w_param, LPARAM l_param)
{
  bool
    use_default = true;

  LRESULT
    result = 0;

  switch (message)
  {
  case WM_CREATE:
    {
      RECT
        client;

      GetClientRect (window, &client);

      CreateWindowEx (0,
                      TEXT ("EditboxClass"),
                      0,
                      WS_VISIBLE | WS_CHILD,
                      client.right / 4,
                      client.bottom / 2 - 20,
                      client.right / 2,
                      40,
                      window,
                      0,
                      GetModuleHandle (0),
                      0);
    }
    break;
  }

  return use_default ? DefWindowProc (window, message, w_param, l_param) : result;
}

int __stdcall WinMain (HINSTANCE instance, HINSTANCE prev_instance, LPSTR command_line, int show)
{
  WNDCLASSEX
    window_class = 
    {
      sizeof window_class,
      0,
      WindowProc,
      0,
      0,
      instance,
      0,
      0,
      reinterpret_cast <HBRUSH> (static_cast <int> (COLOR_WINDOW) + 1),
      0,
      TEXT ("WindowClass"),
      0
    },
    editbox_class = 
    {
      sizeof editbox_class,
      0,
      EditboxProc,
      0,
      0,
      instance,
      0,
      0,
      reinterpret_cast <HBRUSH> (static_cast <int> (COLOR_BTNFACE) + 1),
      0,
      TEXT ("EditboxClass"),
      0
    }; 

  if (RegisterClassEx (&window_class) && RegisterClassEx (&editbox_class))
  {
    HWND
      window = CreateWindowEx (0,
                               TEXT ("WindowClass"),
                               TEXT ("Demo"),
                               WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                               CW_USEDEFAULT,
                               CW_USEDEFAULT,
                               CW_USEDEFAULT,
                               CW_USEDEFAULT,
                               0,
                               0,
                               instance,
                               0);

    if (window)
    {
      MSG
        message;

      bool
        quit = false;

      while (!quit)
      {
        switch (GetMessage (&message, window, 0, 0))
        {
        case -1:
        case 0:
          quit = true;
          break;

        default:
          TranslateMessage (&message);
          DispatchMessage (&message);
          break;
        }
      }
    }
  }

  return 0;
}

それは少し骨の折れるものですが、あなたが望むことをどのように行うかについてあなたにいくつかのアイデアを与えるはずです。編集ボックスの親(フレームをレンダリングするもの)のカスタムコントロールを使用するため、リソーススクリプトを使用して定義されたダイアログ(リソースを手動でコーディングしてからしばらく経っていると思います)では機能しません。EditboxProcにハンドラーを追加して、エディットコントロールとの間のパスメッセージ(WM_NOTIFY、WM_COMMAND、WM_GETTEXTなど)を処理し、角の丸い(WM_PAINT、WM_ERASEBKGND)をレンダリングすることをお勧めします。

于 2012-05-14T08:34:14.883 に答える