In the previous article, I briefly explained how to implement the watermark effect in textbox. It is incorrect to move the same Implementation Method to ComboBox, although Code There was no error in running, but it could not reach our application effect on Textbox, and we could not see the watermark at all. What's going on?
Like Textbox, ComboBox encapsulates the Native Windows Control ComboBox. By using spy ++ to view the ComboBox control, it is not difficult to find that there is a window in ComboBox, which is actually used to edit text. It is an edit control, comboBox only implements the drop-down list function. Therefore, to implement the watermark effect on the ComboBox, you must draw the watermark on its internal native edit control, rather than on the ComboBox. Because the internal edit is Windows native, it cannot be obtained through the control. controls set, so it can only be implemented through Windows API.
In Windows API, The enumchildwindows function can enumerate all the subwindows of a specified window through callback. I will not detail the usage of this function here, if you are interested, refer to the relevant description in msdn. Because the native ComboBox has only one sub-control, it is not difficult to obtain the internal edit. For specific implementation, see the following code, which is taken from the source code of the watermarkcombobox class provided by me. /// <Summary>
/// Obtain the internal edit handle.
/// </Summary>
Private Void Retreiveeditcontrol ()
{
Intptr handle = New Intptr ();
Enumchildwindows (This. Handle, getchildcallback,RefHandle );
This. _ Edithandle=Handle;
}
/// <Summary>
/// The callback function of enumchildwindows.
/// </Summary>
Private Bool Getchildcallback (intptr hwnd, Ref Intptr lparam)
{
// Because native ComboBox has only one sub-control, direct return is not required for any judgment.
Lparam = Hwnd;
Return False ;
}
from the above code, we can see that _ edithandle is the handle of the internal edit control. In this way, you only need to make two modifications compared with the drawing code of the textbox watermark.
The first modification is to obtain the rectangle of the drawn area. Because edit is not a. Net control, you can only use the API function getclientrect, but not the this. clientrectangle attribute.
the second modification is the acquisition of graphics. Instead, the graphics. fromhwnd method is used.
the modified Code is as follows:
code highlighting produced by actipro codehighlighter (freeware)
http://www.CodeHighlighter.com/
--> brush = systembrushes. graytext;
font = This . font;
rect = New rect ();
// obtain the size of the customer region of Edit through APIS.
getclientrect (_ edithandle, ref rect );
stringformat = New stringformat ();
stringformat. alignment = stringalignment. near;
stringformat. linealignment = stringalignment. center;
//Graphics is obtained from the edit handle.
Using(Graphics g=Graphics. fromhwnd (_ edithandle ))
{
G. drawstring (_ watermark, Font, brush, rect. torectangle (), stringformat );
}
//Release unmanaged resources.
Stringformat. Dispose ();
In this way, the watermark function on ComboBox is complete, but there are still two bugs.
1. When the form appears, the watermark will not be displayed immediately. It will only be displayed after the mouse is moved above.
2. the blinking of the watermark is obvious, especially after the visual topic is enabled.
I still don't know the cause of the above two problems. It is probably related to messages. Because the messages processed in the wndproc method are sent to this control, and edit is not equal to the ComboBox itself, it may cause abnormal behavior. To solve this problem, it seems that you can only start from other aspects, first sell a customs token.ArticleI will mention the solution to this problem.
As follows:
NO content entered
After the user name is entered
Demonstration in this articleProgramAndSource codeClick here to download.