First of all, I would like to thank you for your guidance to your younger brother for so long and for providing more than n help to the younger brother, so that I can meet you in my first technical article so quickly! Today is my younger brother's 20th birthday. No one will celebrate it for me. So I write an article to commemorate it and wish myself a happy birthday! ^ O ^
I have been learning Delphi for half a year, and many friends are very interested in hook. So I wrote an impromptu article. In csdn, the younger brother once published a piece of "Delphi's mu window Code" (AH). Since I learned it soon, so there are a lot of points that are not perfect. This article will reintroduce the usage of the message hook function in windows and the subclass processing in windows. I hope it will help you.
Okay, it's time to go into the topic after such a long talk. The hook introduction is no longer here. There are many examples and articles available for reference in the past, but Google or Baidu is not enough! Pai_^
First, let's take a look at the functions for installing the HOOK:
Hhook setwindowshookex (INT idhook, // hookproc lpfn, // hook callback function hinstance hmod, // process DWORD dwthreadid // program thread, if it is 0, it is a global hook );
Familiar with the setwindowshookex function, we can start our work and hook the process. First open Delphi and create a DLL Project (DLL wizard ). Create a new unit (unit1 ). First, declare the function to be used under the interface of the unit.
VaR oldhook: hhook; histance: histance; oldproc: farproc;
The first function is to install hook. Let's take a look at the Code:
Function sethook: Boolean; stdcall; begin oldhook: = setwindowshookex (wh_keyboard, @ hookproc, histance, 0); If (oldhook = 0) Then exit else result: = true; end;
In this case, a global keyboard hook will be installed, and there are many hook methods, so we will not list them here.
The following describes the callback functions:
Function hookproc (ncode, wparam, lparam: integer); integer; stdcall; begin result: = callnexthookex (oldhook, ncode, wparam, lparam); end;
This completes the process hook. However, our work has not ended. On the contrary, our work has just begun. The function of the hook is to help us inject the DLL into others' process spaces. Now our DLL is in another process space. So we can do what we want to do.
The following describes how to subscribe to Windows.
As we all know, no matter what you do in windows, a message will be sent to Windows, and then it will be returned to the application that sends the message after the corresponding processing is made by windows. Then you will ask, "isn't the hook intercepted Windows messages ?"
Yes, it also depends on what messages are intercepted, just like the wh_keyboard we wrote above. We have intercepted keyboard messages, and we can process them when pressing any key. There are many types of messages. However, what we want to talk about today is the subclass processing of windows, which is a new technology. This is the beginning. Pai_^
I believe everyone has seen these two APIs: getwindowslong and setwindowlong. Maybe you will say that these are not window messages processed? Yes, this is the API we will use.
Next, let's take a look at the parameters of these Apis. Long getwindowlong (hwnd, // form handle int nindex // The information to be retrieved, refer to the following table ); the nindex value can be any of the following gwl_exstyle extended window styles gwl_style window styles gwl_wndproc the address of the window function of the window gwl_hinstance has the handle of the window instance gwl_hwndparent the handle of the father of the window. Do not use setwindowword to change the meaning of the guid gwl_userdata of a subwindow in the gwl_id dialog box. The application specifies the meaning of the value dwl_msgresult returned by a message processed by the dwl_msgresult function in the dialog box. specified by the application
You may notice the gwl_wndproc parameter. That's right. We use this parameter for subclass processing. The Code is as follows: oldproc: = getwindowlong (hwnd, gwl_wndproc );
In this way, our oldproc points to the window function address of the form. Now that the window function address is obtained, modify it to our custom message processing address. The setwindowlong function is used below. Long setwindowlong (hwnd, // specify the int nindex of the window handle, // The same as the nindex of getwindowlong long dwnewlong // The New Message Processing address );
The Code is as follows: setwindowlong (hwnd, gwl_wndproc, longint (@ winproc ));
In this way, the message of the specified form is transferred to our function for execution;
The callback function is as follows: function winproc (hwnd, MSG, wparam, lparam: longint): lresult; stdcall; beginresult: = callwindowproc (oldproc, hwnd, MSG, wparam, lparam); end; the MSG here is the window message, which is assigned to the Message table.
Section: The article is written here. I believe you should understand what the hook and subclass are. The following explains why messages are not processed in the hook. As mentioned above, hook helps us inject DLL into other processes. Windows sub-classes can only process messages within the process. Therefore, message blocking can be performed only when we reach the process space of others. In this case, everyone can understand it.
Okay, no nonsense. The source code is assigned below. I hope you will have more support! ^_^ (Copy can be used)
######################################## ################################## Unit unit1;
Interfaceuses windows; var oldhook: hhook; // used to save the return value of the hook oldproc: farproc; // used to point to the window message
Function sethook: Boolean; stdcall; function hookproc (ncode, wparam, lparam: integer): integer; stdcall; function winproc (hwnd, MSG, wparam, lparam: longint): lresult; stdcall; implementation {###################################### ######################################## #####} // install hookfunction sethook: boolean; stdcall; var histance: Cardinal; begin // install hook oldhook: = setwindowshookex (wh_keyboard, @ hookproc, histance, 0); If (oldhook = 0) Then exit else result: = true; end;
{####################################### ######################################## ####} // Hook callback function hookproc (ncode, wparam, lparam: integer): integer; stdcall; varwinstr: hwnd; begin // set the hot key if (wparam = vk_f12) then begin winstr: = findwindow (nil, 'window title text'); oldproc: = farproc (getwindowlong (winstr, gwl_wndproc); setwindowlong (winstr, gwl_wndproc, longint (@ winproc); end; // pass the hook to Windows for processing result: = callnexthookex (oldhook, ncode, wparam, lparam); end;
{####################################### ######################################## ####} // Custom windows message processing function winproc (hwnd, MSG, wparam, lparam: longint): lresult; stdcall; begin {process the message here
Case MSG of wm_activateapp: exit; wm_activate: exit; wm_killfocus: exit; wm_setfocus: exit; end; the above messages are blocked when the window loses focus and obtain focus} // pass the window message to Windows for processing result: = callwindowproc (oldproc, hwnd, MSG, wparam, lparam); end; end.
######################################## ##################################
Appendix: Message Types (collected and organized on the Internet)
######################################## ##################################
Wm_null = $0000; wm_create = $0001; wm_destroy = $0002; wm_move = $0003; wm_size = $0005; change the size of a window wm_activate = $0006; a window is activated or is not activated; wm_setfocus = $0007; wm_killfocus = $0008; wm_enable = $ 000a; change the Enable status wm_setredraw = $ 000b; set whether the window can be re-painted wm_settext = $ 000c; the application sends this message to set the window text wm_gettext = $ 000d; the application sends this message to copy the text of the corresponding window to the buffer wm_gettextlength = $ 000e; get the length of the text related to a window (excluding empty characters) wm_paint = $ 000f; require a window to redraw itself wm_close = $0010; send a signal wm_queryendsession = $0011 when a window or application is to be closed; when the user selects the end dialog box or the program calls the exitwindows function wm_quit = $0012, it ends the program running or when the program calls the postquitmessage function wm_queryopen = $0013. When the user window restores the previous size position, send this message to a certain icon wm_erasebkgnd = $0014. When the window background must be erased (for example, when the window size changes) wm_syscolorchange = $0015; when the system color changes, send this message to all top-level windows wm_endsession =0016 0017; when the system process sends the wm_queryendsession message, this message is sent to the application to notify it whether the conversation ends wm_systemerror = $; wm_showwindow = $0018; when the hidden or display window sends this message to the window wm_activateapp = $ 001c; the window to which the message is sent to the application is activated and the window is not activated; wm_fontchange = $ 001d; send this message to all top-level windows when the system's font repository changes. wm_timechange = $ 001e; send this message to all top-level windows wm_cancelmode = $ 001f when the system time changes; send this message to cancel some ongoing touch state (operation) wm_setcursor = $0020; if the mouse causes the cursor to move in a window and the mouse input is not captured, send a message to the window wm_mouseactivate = $0021; when the cursor is in an inactive window and the user is pressing a key of the mouse to send this message to the current window wm_childactivate = $0022; send this message to the MDI subwindow when the user clicks the title bar of this window, or when the window is activated, moved, and changed the size wm_queuesync = $0023; this message is sent by a computer-based training program, the wh_journalpalyback hook program separates the user input message wm_getminmaxinfo = $0024; this message is sent to the window when it is about to change the size or position; wm_painticon = $0026; send to the minimization window when its icon is to be re-painted wm_iconerasebkgnd = $0027; this message is sent to a minimization window, this message is sent to a dialog box program to change the focus position wm_spoolerstatus = $ 002a; the message wm_drawitem = $ 002b is sent every time a job is added or removed in the print management queue; When button, ComboBox, ListBox, this message is sent to the owner wm_measureitem = $ 002c of these empty parts when the visual appearance of menu is changed. When button, combo box, list box, List View control, or when menu item is created, this message is sent to the control owner wm_deleteitem = $ 002d. When the list box or combo box is destroyed or some items are deleted, lb_deletestring, lb_resetcontent, cb_deletestring, or cb_resetcontent message wm_vkeytoitem = $ 002e; this message has an lbs_wantkeyboardinput style sent to its owner to respond to the wm_keydown message wm_chartoitem = $ 002f; this message is sent to its owner by a lbs_wantkeyboardinput-style list box in response to the wm_char message wm_setfont = $0030. When drawing the text, the program sends this message to obtain the color of the control wm_getfont = $0031; the application sends this message to get the font wm_sethotkey = $0032 of the text drawn by the current control. The application sends this message to connect a window to a hotkey. wm_gethotkey = $0033; the application sends this message to determine whether the hotkey is associated with a window wm_querydragicon = $0037. This message is sent to the minimal window, when the window is to be dragged and its class does not have a defined icon, the application can return an icon or a cursor handle, when you drag and drop the icon, the system displays the icon or the cursor wm_compareitem = $0039; send this message to determine the relative position of the newly added items in ComboBox or ListBox wm_getobject = $ 003d; wm_compacting = $0041; indicates that the memory is too small. wm_windowposchanging = $0046; when the size and position of the window to which the message is sent are about to be changed, to call the setwindowpos function or other window management functions wm_windowposchanged = $0047; when the size and position of the window to which the message is sent have been changed, to call the setwindowpos function or other window management functions wm_power = $0048; (applicable to 16-bit windows) when the system is about to enter the pause status, send this message wm_copydata = $ 004a; the message wm_canceljournal = $ 004b is sent when an application transmits data to another application. When a user cancels the activation status of the program log, the message is submitted to the program wm_notify = $ 004e; when an event of a control has occurred or the control needs to obtain some information, send the message to its parent window wm_inputlangchangerequest = $0050. When you select an input language, or wm_inputlangchange = $0051 for the input language's hot key; send this message to the affected top-level window wm_tcard = $0052 when the platform's field has been changed; this message is sent to the application wm_help = $0053 when the program has initialized the Windows Help routine. This message shows that the user has pressed F1. If a menu is activated, send the message to a menu associated with this window; otherwise, it is sent to a window with focus. If no focus exists, send the message to the currently activated window wm_userchanged = $0054. When the user has logged on or exited, send the message to all windows, when a user logs on or exits, the system updates the user's specific settings. When the user updates the settings, the system immediately sends this message. wm_policyformat = $0055; public control, the custom control and its parent window use this message to determine whether the control uses the ANSI or Unicode structure in the wm_notify message, using this control allows a control to communicate with its parent control wm_contextmenu = $ 007b; right-click a window and send the message to wm_stylechanging = $ 007c; this message is sent to the window wm_stylechanged = $ 007d when the setwindowlong function is called to change the style of one or more windows; send this message to the window wm_displaychange = $ 007e when you call the setwindowlong function in one or more windows; when the resolution of the display changes, send this message to all windows wm_geticon = $ 007f; this message is sent to a window to return the handle of the large icon or small icon associated with a window; wm_seticon = $0080; the program sends this message to associate a new large or small icon with a window; wm_nccreate = $0081; When a window is created for the first time, this message is sent before the wm_create message is sent; wm_ncdestroy = $0082; this message notifies a window where wm_nccalcsize = $0083 is being destroyed in a non-customer zone; wm_nchittest = $0084; // wm_ncpaint = $0085 when you move the mouse, hold down or release the mouse when the customer region of a window must be calculated; the program sends this message to a window. When the frame of the window must be drawn, wm_ncactivate = $0086; this message is sent to a window only when its non-customer zone needs to be changed to show whether it is activated or not activated; wm_getdlgcode = $0087; send this message to a control associated with the dialog box program. The Widdows control orientation key and the tab key enable the input to enter this control by responding to the wm_getdlgcode message, the application can treat it as a special input control and process it wm_ncmousemove = $00a0; when the cursor moves in a non-customer area of a window, the message is sent to this window // non-customer area: the title bar of the form and the border body wm_nclbuttondown of the window = $00a1; the message wm_nclbuttonup = $00a2 is submitted when the cursor is pressed in the non-customer area of a window. When the user releases the left mouse button, the cursor sends the message in the non-customer area 10; wm_nclbuttondblclk = $00a3; when you double-click the left mouse button and send the message wm_ncrbuttondown = $00a4 in a window outside the customer area; the message wm_ncrbuttonup = $00a5 is sent when the user presses the right mouse and the cursor is in a non-customer area of the window; the message wm_ncrbuttondblclk = $00a6 is sent when the user releases the right mouse and the cursor is in a non-customer area of the window; when you double-click and right-click the message, and send the message wm_ncmbuttondown = $00a7 in a window outside the customer Zone 10; the message wm_ncmbuttonup = $00a8 is sent when you press the middle mouse button and the cursor is in a non-customer area of the window; the message wm_ncmbuttondblclk = $00a9 is sent when the user releases the middle mouse button and the cursor is in a non-customer area of the window; wm_keyfirst = $0100; wm_keydown = $0100; // press the next key wm_keyup = $0101; // release a key wm_char = $0102; // press a key and wm_keydown has been sent. wm_keyup message wm_deadchar = $0103; when you use the translatemessage function to translate the wm_keyup message, the message is sent to the window with focus wm_syskeydown = $0104. When you press the Alt key and other keys, the message is submitted to the window with focus; wm_syskeyup = $0105; when you release a key and press ALT, submit the message to the window with focus wm_syschar = $0106; when the wm_syskeydown message is translated by the translatemessage function, submit the message to the window with focus wm_sysdeadchar = $0107; when the wm_syskeydown message is translated by the translatemessage function, the message is sent to the window with focus wm_keylast = $0108; wm_initdialog = $0110; this message is sent to it before a dialog box program is displayed, this message is usually used to initialize the control and run other tasks wm_command = $0111. When you select a menu command item or when a control sends a message to its parent window, A shortcut key is translated into wm_syscommand = $0112. When you select a command in the window menu or when you choose to maximize or minimize, the window will receive the message wm_timer = $0113; // a timer event wm_hscroll = $0114 occurs. This message is sent to the window when a standard horizontal scroll bar of a window generates a rolling event, wm_vscroll = $0115 is also sent to the control that owns it. This message is also sent to the window when a standard vertical scroll bar in a window generates a rolling event, send to the control wm_initmenu with it = $0116; send this message when a menu is to be activated, it occurs in a user menu bar or press a menu key, it allows the program to change the menu wm_initmenupopup = $0117 before display; send this message when a drop-down menu or sub-menu is to be activated, it allows the program to change the menu before display, do not change all wm_menuselect =$ 011f; when you select a menu item, send this message to the menu owner (usually the window) wm_menuchar = $0120; when the menu has been activated, the user presses a key (different from the acceleration key) and sends the message to the menu owner; wm_enteridle = $0121; when a modal dialog box or menu enters the no-load status, this message is sent to its owner, when a modal dialog box or menu enters the no-load status, it waits for wm_menurbuttonup = $0122; wm_menudrag = $0123; wm_menugetobject = $0124; dimensions = $0125; wm_menucommand = $0126; wm_changeuistate = $0127; wm_updateuistate = $0128; wm_queryuistate = $0129; wm_ctlcolormsgbox = $0132; send the message to the owner window of the message box before drawing a message box in windows, in the owner window, you can set the text and background color of the message box wm_ctlcoloredit = $0133 by using the handle of the specified display device; the parent window to which the message is sent when an edit control is to be drawn, in the owner window, you can set the text and background color wm_ctlcolorlistbox = $0134 in the edit box by using the handle of the specified display device; when a list box control sends this message to its parent window before being drawn; by responding to this message, in the owner window, you can set the text and background color wm_ctlcolorbtn = $0135 by using the given handle of the display device; when a button control is to be drawn, this message is sent to its parent window. By responding to this message, in the owner window, you can set the text and background color wm_ctlcolordlg = $0136 by using the corresponding display device handle; when a dialog box control sends this message to its parent window before being drawn; by responding to this message, in the owner window, you can set the text background color wm_ctlcolorscrollbar = $0137 by using the handle of the specified display device; when a scroll bar control is to be drawn, this message is sent to its parent window. By responding to this message, the owner window can set the background color wm_ctlcolorstatic = $0138 of the scroll bar by using the given handle of the display device. This message is sent to the parent window when a static control is to be drawn; in response to this message, the owner window can set the text and background color wm_mousefirst = $0200; wm_mousemove = $0200; of the static control by using the handle of the given display device; // move the mouse wm_lbuttondown = $0201; // press the left mouse button wm_lbuttonup = $0202; // release the left mouse button wm_lbuttondblclk = $0203; // double-click the left mouse button wm_rbuttondown = $0204; // right-click wm_rbuttonup = $0205; // right-click wm_rbuttondblclk = $0206; // right-click wm_mbuttondown = $0207; // right-click wm_mbuttonup = $0208; // release wm_mbuttondblclk = $0209; // double-click wm_mousewheel = $ 020a. When the mouse wheel turns, the message is sent to the currently focused control wm_mouselast = $ 020a; wm_parentnotify = $0210; when the MDI child window is created or destroyed, or the user presses the mouse key and the cursor sends the message to its parent window wm_entermenuloop = $0211 in the Child Window; the main window for sending this message notification application that has entered the menu Cycle Mode wm_exitmenuloop = $0212; the main window for sending this message notification application that has exited the menu loop mode wm_nextmenu = $0213; wm_sizing = 532; when the user is adjusting the window size to send this message to the window; through this message application, you can monitor the window size and position and modify them wm_capturechanged = 533; send this message to the window when it loses the captured mouse; wm_moving = 534; send this message when the user moves the window, the message application can monitor the window size and position and modify them; wm_powerbroadcast = 536; this message is sent to the application to notify it of power management events; wm_devicechange = 537; send this message to the application or device driver wm_ime_startcomposition = $ 010d; wm_ime_endcomposition = $ 010e; wm_ime_composition = $ 010f; wm_ime_keylast = $ 010f; wm_ime_setcontext = $0281; cost = $0282; wm_ime_control = $0283; cost = $0284; wm_ime_select = $0285; wm_ime_char = $0286; wm_ime_request = $0288; cost = $0290; wm_ime_keyup = $0291; wm_mdicreate = $0220; the application sends this message to the customer window of multiple documents to create an MDI child window wm_mdidestroy = $0221; the application sends this message to the customer window of multiple documents to close an MDI subwindow wm_mdiactivate = $0222; the application sends this message to the customer window of multiple documents to notify the customer window to activate another MDI subwindow. When the customer window receives this message, it sends the wm_mdiactive message to the MDI subwindow (not activated) activate it; wm_mdirestore = $0223; the program sends this message to the MDI customer window so that the subwindow is restored from the maximum to the original size wm_mdinext = $0224; the program sends this message to the MDI customer window to activate the next or previous window wm_mdimaximize = $0225; the program sends this message to the MDI customer window to maximize an MDI subwindow; wm_mditile = $0226; the program sends this message to the MDI customer window and rearranges all MDI child windows in a tiled manner. wm_mdicascade = $0227; the program sends this message to the MDI customer window and rearranges all MDI child windows in cascade mode wm_mdiiconarrange = $0228; the program sends this message to the MDI customer window to rearrange all the minimized MDI child windows wm_mdigetactive = $0229; the program sends this message to the MDI customer window to find the activated sub-window handle wm_mdisetmenu = $0230; the program sends this message to the MDI customer window. The MDI menu replaces the sub-Window Menu wm_entersizemove = $0231; wm_exitsizemove = $0232; wm_dropfiles = $0233; wm_mdirefreshmenu = $0234; wm_mousehover = $02a1; wm_mouseleave = $02a3; wm_cut = $0300; the program sends this message to an edit box or ComboBox to delete the selected text wm_copy = $0301; the program sends this message to an edit box or ComboBox to copy the selected text to the clipboard wm_paste = $0302; the program sends this message to editcontrol or ComboBox to get the data wm_clear = $0303 from the clipboard; the program sends this message to editcontrol or ComboBox to clear the selected content; wm_undo = $0304; the program sends this message to editcontrol or ComboBox to cancel the last operation wm_renderformat = $0305;
Wm_renderallformats = $0306; wm_destroyclipboard = $0307; send this message to the clipboard owner wm_drawclipboard = $0308 when the enptyclipboard function is called; when the content of the clipboard changes, this message is sent to the first window of the clipboard observation chain; it allows the clipboard observation window to display the new content of the clipboard; wm_paintclipboard = $0309; when the Clipboard contains data in the cf_ownerdiplay format and the client area of the clipboard observation window needs to be re-painted; wm_vscrollclipboard = $ 030a; wm_sizeclipboard = $ 030b; when the Clipboard contains data in the cf_ownerdiplay format and the size of the client area in the clipboard observation window has changed, the message is sent to the clipboard owner through the clipboard observation window; wm_askcbformatname = $ 030c; by clipboard The Panel observation window sends this message to the clipboard owner to request the name of the clipboard in cf_ownerdisplay format wm_changecbchain = $ 030d; send this message to the first window of the clipboard observation chain when a window is moved from the clipboard observation chain; wm_hscrollclipboard = $ 030e; this message is sent to the clipboard owner through a clipboard observation window; it occurs when the Clipboard contains data in the cfownerdispaly format and an event is on the horizontal scroll bar of the clipboard observation window; the owner should scroll the clipboard image and update the value of the scroll bar; wm_querynewpalette = $ 030f; this message is sent to the window that will receive the focus. This message gives the window the opportunity to implement its logical palette wm_paletteischanging = $0310 when receiving the focus; this message notifies all applications wm_palettechanged =0311 when an application is about to implement its logical palette; this message Send this message to all top-level and overlapping windows after a window with focus implements its logical palette to change the system palette wm_hotkey = $0312; when you press the hotkey registered by the registerhotkey function, the message wm_print = 791 is submitted; the application sends this message only when Windows or other applications send a request requesting to draw a part of an application; wm_printclient = 792; wm_handheldfirst = 856; wm_handheldlast = 863; wm_penwinfirst = $0380; wm_penwinlast = $ 038f; cost = $0390; cost = $ 039f; wm_dde_first = $03e0; wm_dde_initiate = wm_dde_first + 0; a dde client program Submit this message and start a session with the server program to respond to the specified program and topic name; wm_dde_terminate = wm_dde_first + 1; a dde application (whether the client or server) submit this message to terminate a session; wm_dde_advise = wm_dde_first + 2; a dde client program submits this message to a DDE Service Program to request the server to update wm_dde_unadvise = wm_dde_first + 3 whenever the data item changes; a dde client notifies a DDE Service program not to update the specified item or a special clipboard format item wm_dde_ack = wm_dde_first + 4 through this message; this message notifies a DDE (Dynamic Data Exchange) program that it has received and is processing wm_dde_poke, wm_dde_execute, wm_dde_data, wm_dde_advise, wm_dde_unadvise, or Wm_dde_initiat message wm_dde_data = wm_dde_first + 5; a dde Service Program submits this message to the DDE client program to transmit a data item to the customer or notify the customer of an available data item wm_dde_request = wm_dde_first + 6; a dde client program submits this message to a DDE Service Program to request the value of a data item; wm_dde_poke = wm_dde_first + 7; a dde client program submits this message to a DDE Service Program, the customer uses this message to request the server to receive an unapproved data item. The server replies to the wm_dde_ack message to indicate whether the server receives this data item. wm_dde_execute = wm_dde_first + 8; a dde client program submits this message to a DDE Service Program to send a string to the server for processing like a serial command. The server responds by submitting the wm_dde_ack message; wm_dde_l Ast = wm_dde_first + 8; wm_app = $8000; wm_user = $0400; this message can help the application customize private messages; //////////////////////////////////////// //// // notification message) refers to a message in which a child control in a window has something to notify the parent window. The notification message is only applicable to standard window controls such as buttons, list boxes, Combo boxes, and edit boxes, as well as Windows 95 public controls such as tree views and list views. For example, clicking or double-clicking a control, selecting some text in the control, and the scroll bar of the operation control will generate a notification message. Twist B n _ c l I c k e d // the user clicks the button B n _ d I s a B l e // The button is disabled B n _ d o u B L e c l I c k e d // The user double-clicked the button B n _ h I l t e // The user highlighted the button B n _ Pa I n t and the button should be re-painted B n _ u n h I L I t e should be removed from the list box of the combo box c B n _ c l o s e u p be closed c B n _ d B L C L k The user double-clicked a string c B n _ d r o p d o w n combo box and pulled out c B n _ e d I t C H a N G E. The user modified the text in the c B n _ e d I t u p D at E edit box will be updated soon. N _ k I l f o c u s combo box lost input focus c B n _ s e l c h a n g e in the combo box selected a c B N _ S E l e n d c a n c e l user selection should be canceled c B n _ s e l e n d o K user selection is legal c B N _ S E t f o c u s combo box get input focus edit box e n _ c h a n g e edit box text has been updated e n _ e r s pa c e edit box memory insufficient e n _ h s c r o l the user clicks the horizontal scroll bar e n _ k I l f o c u s edit box is losing the input focus e n _ m a x t e x T inserted content is truncated e n _ s e t f o c u s edit box to get text in the input focus e n _ u p D at E edit box to be updated E N _ v s c r o l the user clicked the vertical scroll bar message meaning list box l B n _ d B l c l k the user double-clicked a l B N _ e r s Pa insufficient memory in the c e ListBox l B n _ k I l f o c u s ListBox is losing the input focus l B N _ S E L C A N C E L select to be canceled L B n _ s e l c h a n g e selected another l B N _ s e t f o c u s list box to obtain the input focus
######################################## ##################################