如何在win32 C ++中创建自定义形状控件

时间:2012-05-14 08:21:52

标签: c++ winapi visual-c++ graphics

我想创建一个带有圆边的编辑框。我不能使用标准的编辑框控件,因为它会绘制矩形编辑框。

有任何建议或指示如何做到这一点?

1 个答案:

答案 0 :(得分:3)

您有几个选择: -

  1. 创建父控件并在其中包含子无边框文本编辑控件
  2. 子类文本编辑控件并重载NC_PAINT以绘制边框
  3. <强>更新

    在搞乱了一个示例程序之后,我逐渐意识到子类编辑控件并没有真正起作用,并且在线检查确认了这一点(谢谢MS如此一致!)。

    所以只留下选项1和选项3(只是想到它):

    1. 创建您自己的编辑控件
    2. 以下是方法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)。