简体   繁体   English

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

[英]How to create custom shape control in win32 C++

I would like to create a edit box with rounded edges.I cannt use standard edit box control since it would draw rectangular edit box. 我想创建一个带有圆角的编辑框。我不能使用标准的编辑框控件,因为它会绘制矩形的编辑框。

Any suggestions or pointers how to do that? 有什么建议或指示怎么做?

You have a couple of options:- 您有两种选择:

  1. Create a parent control and have a child borderless text edit control inside it 创建一个父控件,并在其中有一个子级无边界文本编辑控件
  2. Sub-class a text edit control and overload the NC_PAINT to draw the border 子类化文本编辑控件,并重载NC_PAINT以绘制边框

UPDATE 更新

After messing around with a sample program, it gradually dawned on me that sub-classing edit controls doesn't really work and checking on-line confirms this (thankyou MS for being so consistent!). 在弄乱了示例程序之后,我逐渐意识到子类化编辑控件并没有真正起作用,并且在线检查证实了这一点(感谢MS如此一致!)。

So that just leaves option 1 and option 3 (just thought of it): 这样就只剩下选项1和选项3(只需考虑一下):

  1. Create your own edit control 创建自己的编辑控件

Here's an example of method 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;
}

It's a bit bare-bones but should give you some idea about how to do what you want. 这有点毛骨悚然,但是应该让您对如何做自己想要的事情有所了解。 It won't work with dialogs defined using resource scripts (I think, it's been a while since I hand coded a resource) as it uses a custom control for the parent of the edit box (the thing that renders the frame). 它不适用于使用资源脚本定义的对话框(我认为,自从我手工编码资源以来已经有一段时间了),因为它使用了自定义控件作为编辑框的父控件(渲染框架的东西)。 You will probably want to add handlers to EditboxProc to handle pass message to and from the edit control (like WM_NOTIFY, WM_COMMAND, WM_GETTEXT, etc) and to render the rounded corners (WM_PAINT, WM_ERASEBKGND). 您可能想要向EditboxProc添加处理程序,以处理与编辑控件之间的传递消息(例如WM_NOTIFY,WM_COMMAND,WM_GETTEXT等),并渲染圆角(WM_PAINT,WM_ERASEBKGND)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM