SDK Answers
SDK Answers
2. MSG Structure
3. The MSG structure contains message information from a thread's message queue.
4. Syntax
5. Copy
6.
7. typedef struct {
8. HWND hwnd;
9. UINT message;
10. WPARAM wParam;
11. LPARAM lParam;
12. DWORD time;
13. POINT pt;
14. } MSG, *PMSG;
15.Members
16. hwnd
17. HWND
18. Handle to the window whose window procedure receives the message. hwnd is
NULL when the message is a thread message.
19. message
20. UINT
21. Specifies the message identifier. Applications can only use the low word; the high
word is reserved by the system.
22. wParam
23. WPARAM
24. Specifies additional information about the message. The exact meaning depends on
the value of the message member.
25. lParam
26. LPARAM
27. Specifies additional information about the message. The exact meaning depends on
the value of the message member.
28. time
29. DWORD
30. Specifies the time at which the message was posted.
31. pt
32. POINT
33. Specifies the cursor position, in screen coordinates, when the message was posted.
34.Requirements
DispatchMessage Function
The DispatchMessage function dispatches a message to a window procedure. It is typically
used to dispatch a message retrieved by the GetMessage function.
Syntax
Copy
LRESULT DispatchMessage(
__in const MSG *lpmsg
);
Parameters
lpmsg [in]
MSG
Return Value
LRESULT
The return value specifies the value returned by the window procedure. Although its meaning
depends on the message being dispatched, the return value generally is ignored.
Remarks
The MSG structure must contain valid message values. If the lpmsg parameter points to a
WM_TIMER message and the lParam parameter of the WM_TIMER message is not
NULL, lParam points to a function that is called instead of the window procedure.
Note that the application is responsible for retrieving and dispatching input messages to the
dialog box. Most applications use the main message loop for this. However, to permit the
user to move to and to select controls by using the keyboard, the application must call
IsDialogMessage. For more information, see Dialog Box Keyboard Interface.
Examples
Requirements
WindowProc Function
Syntax
Copy
LRESULT CALLBACK WindowProc(
__in HWND hwnd,
__in UINT uMsg,
__in WPARAM wParam,
__in LPARAM lParam
);
Parameters
hwnd [in]
HWND
uMsg [in]
UINT
wParam [in]
WPARAM
lParam [in]
LPARAM
Return Value
LRESULT
The return value is the result of the message processing and depends on the message sent.
Remarks
To make your application more robust, you should use structured exception handling to trap
and handle any errors that might occur in the callback. The following code shows the guarded
body (various message handlers) in the __try, and exception filters and exception handler
block in the __except block.
Copy
Behavior
How the system handles uncaught exceptions
type
1 The system suppresses any uncaught exceptions.
The system first terminates the process, and then the Program Compatibility
Assistant (PCA) offers to fix it the next time you run the application. You can
2
disable the PCA mitigation by adding a Compatibility section to the application
manifest.
The system calls the exception filters but suppresses any uncaught exceptions
3
when it leaves the callback scope, without invoking the associated handlers.
The following table shows how a 64-bit version of Windows operating system or WOW64
handles uncaught exceptions. Notice that behavior type 2 only applies to the 64-bit version of
the Windows 7 operating system.
Requirements
WNDCLASSEX Structure
The WNDCLASSEX structure contains window class information. It is used with the
RegisterClassEx and GetClassInfoEx functions.
The WNDCLASSEX structure is similar to the WNDCLASS structure. There are two
differences. WNDCLASSEX includes the cbSize member, which specifies the size of the
structure, and the hIconSm member, which contains a handle to a small icon associated with
the window class.
Syntax
Copy
typedef struct {
UINT cbSize;
UINT style;
WNDPROC lpfnWndProc;
int cbClsExtra;
int cbWndExtra;
HINSTANCE hInstance;
HICON hIcon;
HCURSOR hCursor;
HBRUSH hbrBackground;
LPCTSTR lpszMenuName;
LPCTSTR lpszClassName;
HICON hIconSm;
} WNDCLASSEX, *PWNDCLASSEX;
Members
cbSize
UINT
style
UINT
Specifies the class style(s). This member can be any combination of the Class Styles.
lpfnWndProc
WNDPROC
Pointer to the window procedure. You must use the CallWindowProc function to call
the window procedure. For more information, see WindowProc.
cbClsExtra
int
Specifies the number of extra bytes to allocate following the window-class structure.
The system initializes the bytes to zero.
cbWndExtra
int
Specifies the number of extra bytes to allocate following the window instance. The
system initializes the bytes to zero. If an application uses WNDCLASSEX to register
a dialog box created by using the CLASS directive in the resource file, it must set this
member to DLGWINDOWEXTRA.
hInstance
HINSTANCE
Handle to the instance that contains the window procedure for the class.
hIcon
HICON
Handle to the class icon. This member must be a handle to an icon resource. If this
member is NULL, the system provides a default icon.
hCursor
HCURSOR
Handle to the class cursor. This member must be a handle to a cursor resource. If this
member is NULL, an application must explicitly set the cursor shape whenever the
mouse moves into the application's window.
hbrBackground
HBRUSH
Handle to the class background brush. This member can be a handle to the physical
brush to be used for painting the background, or it can be a color value. A color value
must be one of the following standard system colors (the value 1 must be added to the
chosen color). If a color value is given, you must convert it to one of the following
HBRUSH types:
COLOR_ACTIVEBORDER
COLOR_ACTIVECAPTION
COLOR_APPWORKSPACE
COLOR_BACKGROUND
COLOR_BTNFACE
COLOR_BTNSHADOW
COLOR_BTNTEXT
COLOR_CAPTIONTEXT
COLOR_GRAYTEXT
COLOR_HIGHLIGHT
COLOR_HIGHLIGHTTEXT
COLOR_INACTIVEBORDER
COLOR_INACTIVECAPTION
COLOR_MENU
COLOR_MENUTEXT
COLOR_SCROLLBAR
COLOR_WINDOW
COLOR_WINDOWFRAME
COLOR_WINDOWTEXT
The system automatically deletes class background brushes when the class is
unregistered by using UnregisterClass. An application should not delete these
brushes.
When this member is NULL, an application must paint its own background whenever
it is requested to paint in its client area. To determine whether the background must be
painted, an application can either process the WM_ERASEBKGND message or test
the fErase member of the PAINTSTRUCT structure filled by the BeginPaint
function.
lpszMenuName
LPCTSTR
Pointer to a null-terminated character string that specifies the resource name of the
class menu, as the name appears in the resource file. If you use an integer to identify
the menu, use the MAKEINTRESOURCE macro. If this member is NULL,
windows belonging to this class have no default menu.
lpszClassName
LPCTSTR
If lpszClassName is a string, it specifies the window class name. The class name can
be any name registered with RegisterClass or RegisterClassEx, or any of the
predefined control-class names.
hIconSm
HICON
Handle to a small icon that is associated with the window class. If this member is
NULL, the system searches the icon resource specified by the hIcon member for an
icon of the appropriate size to use as the small icon.
Requirements
See Also
Reference
GetClassInfoEx
RegisterClassEx
UnregisterClass
ShowWindow Function
Syntax
Copy
BOOL ShowWindow(
__in HWND hWnd,
__in int nCmdShow
);
Parameters
hWnd [in]
HWND
nCmdShow [in]
int
Specifies how the window is to be shown. This parameter is ignored the first time an
application calls ShowWindow, if the program that launched the application provides
a STARTUPINFO structure. Otherwise, the first time ShowWindow is called, the
value should be the value obtained by the WinMain function in its nCmdShow
parameter. In subsequent calls, this parameter can be one of the following values.
SW_FORCEMINIMIZE
Minimizes a window, even if the thread that owns the window is not responding. This
flag should only be used when minimizing windows from a different thread.
SW_HIDE
SW_MAXIMIZE
SW_MINIMIZE
Minimizes the specified window and activates the next top-level window in the Z
order.
SW_RESTORE
Activates and displays the window. If the window is minimized or maximized, the
system restores it to its original size and position. An application should specify this
flag when restoring a minimized window.
SW_SHOW
Activates the window and displays it in its current size and position.
SW_SHOWDEFAULT
Sets the show state based on the SW_ value specified in the STARTUPINFO
structure passed to the CreateProcess function by the program that started the
application.
SW_SHOWMAXIMIZED
SW_SHOWMINIMIZED
SW_SHOWMINNOACTIVE
SW_SHOWNA
Displays the window in its current size and position. This value is similar to
SW_SHOW, except the window is not activated.
SW_SHOWNOACTIVATE
Displays a window in its most recent size and position. This value is similar to
SW_SHOWNORMAL, except the window is not actived.
SW_SHOWNORMAL
Return Value
BOOL
Remarks
To perform certain special effects when showing or hiding a window, use AnimateWindow.
The first time an application calls ShowWindow, it should use the WinMain function's
nCmdShow parameter as its nCmdShow parameter. Subsequent calls to ShowWindow must
use one of the values in the given list, instead of the one specified by the WinMain function's
nCmdShow parameter.
As noted in the discussion of the nCmdShow parameter, the nCmdShow value is ignored in
the first call to ShowWindow if the program that launched the application specifies startup
information in the structure. In this case, ShowWindow uses the information specified in the
STARTUPINFO structure to show the window. On subsequent calls, the application must
call ShowWindow with nCmdShow set to SW_SHOWDEFAULT to use the startup
information provided by the program that launched the application. This behavior is designed
for the following situations:
Examples
Requirements
CreateWindow Function
The CreateWindow function creates an overlapped, pop-up, or child window. It specifies the
window class, window title, window style, and (optionally) the initial position and size of the
window. The function also specifies the window's parent or owner, if any, and the window's
menu.
To use extended window styles in addition to the styles supported by CreateWindow, use
the CreateWindowEx function.
Syntax
Copy
HWND CreateWindow(
__in LPCTSTR lpClassName,
__in LPCTSTR lpWindowName,
__in DWORD dwStyle,
__in int x,
__in int y,
__in int nWidth,
__in int nHeight,
__in HWND hWndParent,
__in HMENU hMenu,
__in HINSTANCE hInstance,
__in LPVOID lpParam
);
Parameters
lpClassName [in]
LPCTSTR
lpWindowName [in]
LPCTSTR
Pointer to a null-terminated string that specifies the window name. If the window
style specifies a title bar, the window title pointed to by lpWindowName is displayed
in the title bar. When using CreateWindow to create controls, such as buttons, check
boxes, and static controls, use lpWindowName to specify the text of the control. When
creating a static control with the SS_ICON style, use lpWindowName to specify the
icon name or identifier. To specify an identifier, use the syntax "#num".
dwStyle [in]
DWORD
Specifies the style of the window being created. This parameter can be a combination
of
window styles
, plus the control styles indicated in the Remarks section.
x [in]
int
Specifies the initial horizontal position of the window. For an overlapped or pop-up
window, the x parameter is the initial x-coordinate of the window's upper-left corner,
in screen coordinates. For a child window, x is the x-coordinate of the upper-left
corner of the window relative to the upper-left corner of the parent window's client
area. If this parameter is set to CW_USEDEFAULT, the system selects the default
position for the window's upper-left corner and ignores the y parameter.
CW_USEDEFAULT is valid only for overlapped windows; if it is specified for a
pop-up or child window, the x and y parameters are set to zero.
y [in]
int
Specifies the initial vertical position of the window. For an overlapped or pop-up
window, the y parameter is the initial y-coordinate of the window's upper-left corner,
in screen coordinates. For a child window, y is the initial y-coordinate of the upper-
left corner of the child window relative to the upper-left corner of the parent window's
client area. For a list box, y is the initial y-coordinate of the upper-left corner of the
list box's client area relative to the upper-left corner of the parent window's client
area.
If an overlapped window is created with the WS_VISIBLE style bit set and the x
parameter is set to CW_USEDEFAULT, then the y parameter determines how the
window is shown. If the y parameter is CW_USEDEFAULT, then the window
manager calls ShowWindow with the SW_SHOW flag after the window has been
created. If the y parameter is some other value, then the window manager calls
ShowWindow with that value as the nCmdShow parameter.
nWidth [in]
int
Specifies the width, in device units, of the window. For overlapped windows, nWidth
is either the window's width, in screen coordinates, or CW_USEDEFAULT. If
nWidth is CW_USEDEFAULT, the system selects a default width and height for the
window; the default width extends from the initial x-coordinate to the right edge of
the screen, and the default height extends from the initial y-coordinate to the top of
the icon area. CW_USEDEFAULT is valid only for overlapped windows; if
CW_USEDEFAULT is specified for a pop-up or child window, nWidth and nHeight
are set to zero.
nHeight [in]
int
Specifies the height, in device units, of the window. For overlapped windows,
nHeight is the window's height, in screen coordinates. If nWidth is set to
CW_USEDEFAULT, the system ignores nHeight.
hWndParent [in]
HWND
Handle to the parent or owner window of the window being created. To create a child
window or an owned window, supply a valid window handle. This parameter is
optional for pop-up windows.
hInstance [in]
HINSTANCE
lpParam [in]
LPVOID
Return Value
HWND
If the function succeeds, the return value is a handle to the new window.
If the function fails, the return value is NULL. To get extended error information, call
GetLastError.
Remarks
Before returning, CreateWindow sends a WM_CREATE message to the window
procedure. For overlapped, pop-up, and child windows, CreateWindow sends
WM_CREATE, WM_GETMINMAXINFO, and WM_NCCREATE messages to the
window. The lParam parameter of the WM_CREATE message contains a pointer to a
CREATESTRUCT structure. If the WS_VISIBLE style is specified, CreateWindow sends
the window all the messages required to activate and show the window.
If the created window is a child window, its default position is at the bottom of the Z-order. If
the created window is a top-level window, its default position is at the top of the Z-order (but
beneath all topmost windows unless the created window is itself topmost).
For information on controlling whether the Taskbar displays a button for the created window,
see Managing Taskbar Buttons.
The following predefined system classes can be specified in the lpClassName parameter.
Note the corresponding control styles you can use in the dwStyle parameter.
For a table of the button styles you can specify in the dwStyle parameter,
see Button Styles.
Designates a control consisting of a list box and a selection field similar
to an edit control. When using this style, an application should either
display the list box at all times or enable a drop-down list box. If the list
box is visible, typing characters into the selection field highlights the
first list box entry that matches the characters typed. Conversely,
COMBOBOX
selecting an item in the list box displays the selected text in the selection
field.
For more information, see Combo Boxes. For a table of the combo box
styles you can specify in the dwStyle parameter, see Combo Box Styles.
Designates a rectangular child window into which the user can type text
from the keyboard. The user selects the control and gives it the keyboard
focus by clicking it or moving to it by pressing the TAB key. The user
can type text when the edit control displays a flashing caret; use the
mouse to move the cursor, select characters to be replaced, or position
EDIT
the cursor for inserting characters; or use the BACKSPACE key to
delete characters. For more information, see Edit Controls.
For a table of the edit control styles you can specify in the dwStyle
parameter, see Edit Control Styles.
LISTBOX Designates a list of character strings. Specify this control whenever an
application must present a list of names, such as file names, from which
the user can choose. The user can select a string by clicking it. A
selected string is highlighted, and a notification message is passed to the
parent window. For more information, see List Boxes.
For a table of the list box styles you can specify in the dwStyle
parameter, see List Box Styles.
Designates an MDI client window. This window receives messages that
control the MDI application's child windows. The recommended style
bits are WS_CLIPCHILDREN and WS_CHILD. Specify the
MDICLIENT WS_HSCROLL and WS_VSCROLL styles to create an MDI client
window that allows the user to scroll MDI child windows into view.
For a table of the rich edit control styles you can specify in the dwStyle
parameter, see Rich Edit Control Styles.
Designates a Microsoft Rich Edit 2.0 control. This controls let the user
view and edit text with character and paragraph formatting, and can
include embedded COM objects. For more information, see Rich Edit
RICHEDIT_CLASS Controls.
For a table of the rich edit control styles you can specify in the dwStyle
parameter, see Rich Edit Control Styles.
Designates a rectangle that contains a scroll box and has direction
arrows at both ends. The scroll bar sends a notification message to its
parent window whenever the user clicks the control. The parent window
is responsible for updating the position of the scroll box, if necessary.
SCROLLBAR
For more information, see Scroll Bars.
For a table of the scroll bar control styles you can specify in the dwStyle
parameter, see Scroll Bar Control Styles.
Designates a simple text field, box, or rectangle used to label, box, or
separate other controls. Static controls take no input and provide no
output. For more information, see Static Controls.
STATIC
For a table of the static control styles you can specify in the dwStyle
parameter, see Static Control Styles.
Examples
--------------------------------------------------------------------------------------------------------------------------------
-
You can determine whether a DLL function requires a callback function by looking at its
arguments and reading the documentation for the function. An argument that takes a pointer
to a callback function is a long pointer, usually prefaced with the prefix "lp". Also, the name
of the argument usually ends in "Func", indicating that it takes a pointer to a function. For
example, take a look at the Declare statement for the EnumWindows function. The
lpEnumFunc argument indicates that the function requires a callback function.
So how do you know what the callback function should look like? The answer is in the
documentation for the function. Each callback function has different arguments.
Unfortunately, although information about DLL functions requiring callbacks is available in
Win32API.txt, information about creating the callback functions themselves is not.
The Microsoft Platform SDK, available on the Microsoft Developer Network site at
http://msdn.microsoft.com, contains information about all DLL functions that require
callbacks and their corresponding callback functions, and is probably the best source for this
information. However, in order to use it, you need to be able to interpret C/C++
documentation and translate it to VBA.
You can name the callback function whatever you want to; the suggested name is usually the
name of the DLL function, followed by "Proc". For example, the suggested name for the
callback function of the EnumWindows function is EnumWindowsProc. Note that you can
have more than one callback function for the same DLL function.
Here's the C/C++ definition for the EnumWindowsProc function, as described in the Platform
SDK:
Callback functions usually return a Long value - nonzero for success, zero for failure. To
continue enumerating, a callback function must return True, so you must explicitly set the
return value to True within the function. Setting it to False halts the enumeration. The
function will run until it either finishes enumerating or returns False.
Important Be careful when defining the callback function. You must include the ByVal
keyword where necessary, and you must include the return value for the function. Also, the
function must be declared exactly according to the documentation. If you don't define the
function correctly, your solution will most likely cause an application error when you try to
run it.
When you call the EnumWindows function, this function calls the EnumWindowsProc
function in your VBA project for each existing window, passing in the window's handle and
whatever value is contained in the lParam argument. You can add whatever code you want
within the callback function.
The following example shows a callback function for the EnumWindows function. This
callback function, EnumWindowsProc, adds each visible parent window to the
ParentWindows collection, a custom collection of ParentWindow objects. In order to add
windows to the collection, the collection object is passed into the callback function in the
lParam argument. The procedure calls two other functions: the IsWindowVisible API
function, which determines whether a given window is visible, and the GetWindowCaption
procedure, which in turn calls the GetWindowText API function to return the window's
caption.
Note Parent windows are primary application windows; child windows are windows that
exist within parent windows. A separate DLL function, EnumChildWindows, exists for
enumerating child windows within parent windows. The EnumWindows.xls sample file
demonstrates both functions.
Once the ParentWindows collection has been initialized, you can refer to a ParentWindow
object within the collection by its index or by its key, which is the window's handle. Use the
Item property of the ParentWindows collection to refer to a member of the collection. For
example, the following code fragment prints the caption of the third ParentWindow object in
the ParentWindows collection:
Debug.Print ParentWindows.Item(3).Caption
GetMessage Function
The GetMessage function retrieves a message from the calling thread's message queue. The
function dispatches incoming sent messages until a posted message is available for retrieval.
Unlike GetMessage, the PeekMessage function does not wait for a message to be posted
before returning.
Syntax
Copy
BOOL GetMessage(
__out LPMSG lpMsg,
__in HWND hWnd,
__in UINT wMsgFilterMin,
__in UINT wMsgFilterMax
);
Parameters
lpMsg [out]
LPMSG
Pointer to an MSG structure that receives message information from the thread's
message queue.
hWnd [in]
HWND
Handle to the window whose messages are to be retrieved. The window must belong
to the current thread.
If hWnd is NULL, GetMessage retrieves messages for any window that belongs to
the current thread, and any messages on the current thread's message queue whose
hwnd value is NULL (see the MSG structure). Therefore if hWnd is NULL, both
window messages and thread messages are processed.
If hWnd is -1, GetMessage retrieves only messages on the current thread's message
queue whose hwnd value is NULL, that is, thread messages as posted by
PostMessage (when the hWnd parameter is NULL) or PostThreadMessage.
wMsgFilterMin [in]
UINT
Specifies the integer value of the lowest message value to be retrieved. Use
WM_KEYFIRST to specify the first keyboard message or WM_MOUSEFIRST to
specify the first mouse message.
Windows XP: Use WM_INPUT here and in wMsgFilterMax to specify only the
WM_INPUT messages.
wMsgFilterMax [in]
UINT
Specifies the integer value of the highest message value to be retrieved. Use
WM_KEYLAST to specify the last keyboard message or WM_MOUSELAST to
specify the last mouse message.
Windows XP: Use WM_INPUT here and in wMsgFilterMin to specify only the
WM_INPUT messages.
If wMsgFilterMin and wMsgFilterMax are both zero, GetMessage returns all
available messages (that is, no range filtering is performed).
Return Value
BOOL
If the function retrieves a message other than WM_QUIT, the return value is nonzero.
If the function retrieves the WM_QUIT message, the return value is zero.
If there is an error, the return value is -1. For example, the function fails if hWnd is an invalid
window handle or lpMsg is an invalid pointer. To get extended error information, call
GetLastError.
Warning
Because the return value can be nonzero, zero, or -1, avoid code like this:
Copy
while (GetMessage( lpMsg, hWnd, 0, 0)) ...
The possibility of a -1 return value means that such code can lead to fatal application errors.
Instead, use code like this:
Copy
BOOL bRet;
Remarks
An application typically uses the return value to determine whether to end the main message
loop and exit the program.
The GetMessage function retrieves messages associated with the window identified by the
hWnd parameter or any of its children, as specified by the IsChild function, and within the
range of message values given by the wMsgFilterMin and wMsgFilterMax parameters. Note
that an application can only use the low word in the wMsgFilterMin and wMsgFilterMax
parameters; the high word is reserved for the system.
Note that GetMessage always retrieves WM_QUIT messages, no matter which values you
specify for wMsgFilterMin and wMsgFilterMax.
During this call, the system delivers pending, nonqueued messages, that is, messages sent to
windows owned by the calling thread using the SendMessage, SendMessageCallback,
SendMessageTimeout, or SendNotifyMessage function. Then the first queued message that
matches the specified filter is retrieved. The system may also process internal events. If no
filter is specified, messages are processed in the following order:
Sent messages
Posted messages
Input (hardware) messages and system internal events
Sent messages (again)
WM_PAINT messages
WM_TIMER messages
To retrieve input messages before posted messages, use the wMsgFilterMin and
wMsgFilterMax parameters.
GetMessage does not remove WM_PAINT messages from the queue. The messages remain
in the queue until processed.
Windows XP: If a top-level window stops responding to messages for more than several
seconds, the system considers the window to be not responding and replaces it with a ghost
window that has the same z-order, location, size, and visual attributes. This allows the user to
move it, resize it, or even close the application. However, these are the only actions available
because the application is actually not responding. When in the debugger mode, the system
does not generate a ghost window.
Examples
Requirements
After my last post on implementing low-level keyboard hooks in C#, Soumitra asked if it was
possible to implement a low-level mouse hook in C#, too. Sure. Here is an example that will
print out the location of the mouse every time you press the left mouse button down:
class InterceptMouse
{
private static LowLevelMouseProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
private struct MSLLHOOKSTRUCT
{
public POINT pt;
public uint mouseData;
public uint flags;
public uint time;
public IntPtr dwExtraInfo;
}
10. What are virtual key codes? How they are different from Scan codes? How they are different
from ASCII
codes?
11. What arrangements have to be made with the WNDCLASSEX structure of a Window class to
start getting
WM_DBLCLKS messages for double clicks of mouse?
12. What are the contents of wParam and lParam for a mouse message?
13. Which APIs are used to set and destroy Timers?
14. What are the contents of wParam and lParam for the WM_COMMAND message related with
a menu?
15. Write the steps involved in creating a menu through a resource editor.
16. What are the contents of LOWORD(wParam), HIWORD(wParam) and lParam for messages
related with
child window control?
17. A check box is created from a CheckBox class. (T/F)
18. Explain the purpose of the API GetDlgItem()
19. Write a code snippet to demonstrate the use of SendMessage() in context of child window
controls.
20. Name any four system control classes.
21. What are common dialogs? Name three common dialogs.
22. What are windows resources?
23. Name any 5 resources.
24. What is the difference between a modal and a modeless dialog box?
25. Name any 5 GDI objects.
26. What are stock GDI objects?
27. What is a clipboard? What are different clipboard formats?
28. How many bytes are there in a UNICODE character?
29. A dynamic link library gives us better speed performance than a static link library. (T/F)
30. What is a Resource Only Library?
31. Show the hierarchical relationship among a Frame window, Client window and Child window
in a MDI
application.
32. “While programming for Windows in C using SDK, we simulate Object Oriented
Programming”. Justify
this statement
33. In a typical Windows program we have one WinMain() function and one WndProc() function.
34. How is
WndProc() called automatically when there is no explicit call to it in the WinMain() ?
35. When do you get the message WM_PAINT? Why do you trap the WM_PAINT message and
not the
WM_CREATE message to write TextOut() in a typical “HelloWorld” program?
36. What is GDI? Why it is advised to use BeginPaint() and EndPaint() in pairs?
37. What happens when you register a window? How is RegisterClassEx()different from
CreateWindow()?
38. Is it always necessary to call DefWindowProc() at the end of your WndProc()? If not what
extra piece of
code will have to be written by the programmer?
39. What is the difference between the members hIcon and hIconSm of the WNDCLASSEX
structure ?
40. How does Windows achieve device independence by the use of GDI?
41. What type of translation is carried out in the API TranslateMessage() ?
ACTS National Resource Center, Pune
Question Bank –Win32 SDK (Solved)
Page 13 of 13
42. Is it possible to have more WM_KEYDOWN messages than WM_KEYUP messages? When
does such
situation occur?
43. Write an appropriate code snippet to demonstrate the use of InvalidateRect() in response to a
WM_CHAR message?
44. How do you get the status of SHIFT keys while processing a mouse message?
45. Name any 5 menu related messages.
46. What is subclassing? Write the steps and necessary APIs to subclass an edit class.
47. Write a code snippet that is required to bring a Color Dialog Box on screen.
48. In a small piece of code show the use of the API SetCursor().
49. Write the message loop for a program which uses a modeless dialog box.
50. Explain the use of the following APIs:
GetDlgItemText() GetDlgItemInt()
51. Explain the meaning of the following style flags related with a Window Class. CS_CLASSDC,
CS_PARENTDC, CS_OWNDC.
52. Explain with example the use of BitBlit() API.
53. How a logical font is created? Explain with appropriate APIs and Structures.
54. What are Meta files ?
55. Write a small piece of code to demonstrate the creation of a meta file.
56. Explain the following APIs.:
OpenClipboard() IsClipboardFormatAvailable()
57. Explain the following APIs.:
EmptyClipboard(), SetClipboardData(), SetClipboardViewer()
58. How these messages are used.
WM_COPY WM_PASTE
WM_PAINTCLIPBOARD WM_CHANGECBCHAIN
59. How UNICODE can be useful in bringing all the languages on computers?
60. A dynamic link library gives us better speed performance than a static link library. (T/F)Justify
your
answer.
Answer the following in details:
1. Write the steps involved in creating a DLL and then using it in a program. Put two functions
AddTwoNums() and MultiplyTwoNums() inside the DLL. Write the code snippets to create the
DLL.
2. What do you understand by Entry/Exit function in a DLL? How they are used?
3. Explain with example code snippets, the use of following structures.
MDICREATESTRUCT CLIENTCREATESTRUCT
4. Write the messages generated in proper order when a key is pressed which indicates:
System keystroke message
Non-system keystroke message
5. What is meant by a CALLBACK function. Which functions should be declared as CALLBACK?
6. What is window subclassing ? Write the skeleton of the steps required in subclassing a
window.
7. What is the significance of the value returned by the Window Procedure while handling
WM_CREATE
message?
8. What are the values send in WPARAM and LPARAM with the following messages?
WM_PAINT
WM_CREATE
WM_COMMAND
WM_MOUSEMOVE
ACTS National Resource Center, Pune
Question Bank –Win32 SDK (Solved)
Page 14 of 14
9. Write Win32 statements for the following
a. Copy the selected text in a text box to clipboard.
b. Change the state of a radio button.
10. Write Win32 statements for the following
a) Count the number of items in a list box.
b) Change the title of any window.
11. Describe the use of the following APIs/C Library Functions by writing your own sample code:
a) _beginthread()
_beginthread, _beginthreadex
Creates a thread.
Copy
uintptr_t _beginthread(
void( *start_address )( void * ),
unsigned stack_size,
void *arglist
);
uintptr_t _beginthreadex(
void *security,
unsigned stack_size,
unsigned ( *start_address )( void * ),
void *arglist,
unsigned initflag,
unsigned *thrdaddr
);
Parameters
start_address
Start address of a routine that begins execution of a new thread. For _beginthread,
the calling convention is either __cdecl or __clrcall; for _beginthreadex, it is either
__stdcall or __clrcall.
stack_size
arglist
security
initflag
thrdaddr
Points to a 32-bit variable that receives the thread identifier. Might be NULL, in
which case it is not used.
Return Value
If successful, each of these functions returns a handle to the newly created thread; however, if
the newly created thread exits too quickly, _beginthread might not return a valid handle (see
the discussion in the Remarks section). _beginthread returns -1L on an error, in which case
errno is set to EAGAIN if there are too many threads, to EINVAL if the argument is invalid
or the stack size is incorrect, or to EACCES in the case of insufficient resources (such as
memory). _beginthreadex returns 0 on an error, in which case errno and _doserrno are set.
For more information about these and other return codes, see _doserrno, errno, _sys_errlist,
and _sys_nerr.
For more information about uintptr_t, see Standard Types.
Remarks
_beginthreadex resembles the Win32 CreateThread API more closely than _beginthread
does. _beginthreadex differs from _beginthread in the following ways:
The routine at start_address passed to _beginthreadex must use the __stdcall calling
convention and must return a thread exit code.
The _beginthreadex function gives you more control over how the thread is created than
_beginthread does. The _endthreadex function is also more flexible. For example, with
_beginthreadex, you can use security information, set the initial state of the thread (running
or suspended), and get the thread identifier of the newly created thread. You are also able to
use the thread handle returned by _beginthreadex with the synchronization APIs, which you
cannot do with _beginthread.
_endthread automatically closes the thread handle (whereas _endthreadex does not).
Therefore, when using _beginthread and _endthread, do not explicitly close the thread
handle by calling the Win32 CloseHandle API. This behavior differs from the Win32
ExitThread API.
Note
For an executable file linked with Libcmt.lib, do not call the Win32 ExitThread API; this
prevents the run-time system from reclaiming allocated resources. _endthread and
_endthreadex reclaim allocated thread resources and then call ExitThread.
The operating system handles the allocation of the stack when either _beginthread or
_beginthreadex is called; you do not need to pass the address of the thread stack to either of
these functions. In addition, the stack_size argument can be 0, in which case the operating
system uses the same value as the stack specified for the main thread.
arglist is a parameter to be passed to the newly created thread. Typically it is the address of a
data item, such as a character string. arglist can be NULL if it is not needed, but
_beginthread and _beginthreadex must be provided with some value to pass to the new
thread. All threads are terminated if any thread calls abort, exit, _exit, or ExitProcess.
The locale of the new thread is inherited from its parent thread. If per thread locale is enabled
by a call to _configthreadlocale (either globally or for new threads only), the thread can
change its locale independently from its parent by calling setlocale or _wsetlocale. For more
information, see Locale.
For mixed and pure code, _beginthread and _beginthreadex both have two overloads, one
taking a native calling-convention function pointer, the other taking a __clrcall function
pointer. The first overload is not application domain-safe and never will be. If you are writing
mixed or pure code you must ensure that the new thread enters the correct application domain
before it accesses managed resources. You can do this, for example, by using
call_in_appdomain Function. The second overload is application domain-safe; the newly
created thread will always end up in the application domain of the caller of _beginthread or
_beginthreadex.
Requirements
Required
Routine Compatibility
header
Libraries
Multithreaded versions of the C run-time libraries only.
To use _beginthread or _beginthreadex, the application must link with one of the
multithreaded C run-time libraries.
Example
Copy
// crt_BEGTHRD.C
// compile with: /MT /D "_X86_" /c
// processor: x86
#include <windows.h>
#include <process.h> /* _beginthread, _endthread */
#include <stddef.h>
#include <stdlib.h>
#include <conio.h>
int main()
{
CHAR ch = 'A';
/* Bounce - Thread to create and and control a colored letter that moves
* around on the screen.
*
* Params: ch - the letter to be moved
*/
void Bounce( void *ch )
{
/* Generate letter and color attribute from thread argument. */
char blankcell = 0x20;
char blockcell = (char) ch;
BOOL first = TRUE;
COORD oldcoord, newcoord;
DWORD result;
/* Blank out our old position on the screen, and draw new letter.
*/
if( first )
first = FALSE;
else
WriteConsoleOutputCharacter( hStdOut, &blankcell, 1, oldcoord,
&result );
WriteConsoleOutputCharacter( hStdOut, &blockcell, 1, newcoord,
&result );
Input
press any key to end
The following sample code demonstrates how you can use the thread handle returned by
_beginthreadex with the synchronization API WaitForSingleObject. The main thread waits
for the second thread to terminate before it continues. When the second thread calls
_endthreadex, it causes its thread object to go to the signaled state. This allows the primary
thread to continue running. This cannot be done with _beginthread and _endthread, because
_endthread calls CloseHandle, destroying the thread object before it can be set to the
signaled state.
Copy
// crt_begthrdex.cpp
// compile with: /MT
#include <windows.h>
#include <stdio.h>
#include <process.h>
unsigned Counter;
unsigned __stdcall SecondThreadFunc( void* pArguments )
{
printf( "In second thread...\n" );
_endthreadex( 0 );
return 0;
}
int main()
{
HANDLE hThread;
unsigned threadID;
// Wait until second thread terminates. If you comment out the line
// below, Counter will not be correct because the thread has not
// terminated, and Counter most likely has not been incremented to
// 1000000 yet.
WaitForSingleObject( hThread, INFINITE );
printf( "Counter should be 1000000; it is-> %d\n", Counter );
// Destroy the thread object.
CloseHandle( hThread );
}
Output
Creating second thread...
In second thread...
Counter should be 1000000; it is-> 1000000
b) StretchBlt()
StretchBlt Function
The StretchBlt function copies a bitmap from a source rectangle into a destination rectangle,
stretching or compressing the bitmap to fit the dimensions of the destination rectangle, if
necessary. The system stretches or compresses the bitmap according to the stretching mode
currently set in the destination device context.
Syntax
Copy
BOOL StretchBlt(
__in HDC hdcDest,
__in int nXOriginDest,
__in int nYOriginDest,
__in int nWidthDest,
__in int nHeightDest,
__in HDC hdcSrc,
__in int nXOriginSrc,
__in int nYOriginSrc,
__in int nWidthSrc,
__in int nHeightSrc,
__in DWORD dwRop
);
Parameters
hdcDest [in]
nXOriginDest [in]
The x-coordinate, in logical units, of the upper-left corner of the destination rectangle.
nYOriginDest [in]
The y-coordinate, in logical units, of the upper-left corner of the destination rectangle.
nWidthDest [in]
The width, in logical units, of the destination rectangle.
nHeightDest [in]
hdcSrc [in]
nXOriginSrc [in]
The x-coordinate, in logical units, of the upper-left corner of the source rectangle.
nYOriginSrc [in]
The y-coordinate, in logical units, of the upper-left corner of the source rectangle.
nWidthSrc [in]
nHeightSrc [in]
dwRop [in]
The raster operation to be performed. Raster operation codes define how the system
combines colors in output operations that involve a brush, a source bitmap, and a
destination bitmap.
See BitBlt for a list of common raster operation codes (ROPs). Note that the
CAPTUREBLT ROP generally cannot be used for printing device contexts.
Return Value
Remarks
StretchBlt stretches or compresses the source bitmap in memory and then copies the result to
the destination rectangle. This bitmap can be either a compatible bitmap (DDB) or the output
from CreateDIBSection. The color data for pattern or destination pixels is merged after the
stretching or compression occurs.
When an enhanced metafile is being recorded, an error occurs (and the function returns
FALSE) if the source device context identifies an enhanced-metafile device context.
If the specified raster operation requires a brush, the system uses the brush currently selected
into the destination device context.
The destination coordinates are transformed by using the transformation currently specified
for the destination device context; the source coordinates are transformed by using the
transformation currently specified for the source device context.
If destination, source, and pattern bitmaps do not have the same color format, StretchBlt
converts the source and pattern bitmaps to match the destination bitmap.
If StretchBlt must convert a monochrome bitmap to a color bitmap, it sets white bits (1) to
the background color and black bits (0) to the foreground color. To convert a color bitmap to
a monochrome bitmap, it sets pixels that match the background color to white (1) and sets all
other pixels to black (0). The foreground and background colors of the device context with
color are used.
StretchBlt creates a mirror image of a bitmap if the signs of the nWidthSrc and nWidthDest
parameters or if the nHeightSrc and nHeightDest parameters differ. If nWidthSrc and
nWidthDest have different signs, the function creates a mirror image of the bitmap along the
x-axis. If nHeightSrc and nHeightDest have different signs, the function creates a mirror
image of the bitmap along the y-axis.
Not all devices support the StretchBlt function. For more information, see the
GetDeviceCaps.
When used in a multiple monitor system, both hdcSrc and hdcDest must refer to the same
device or the function will fail. To transfer data between DCs for different devices, convert
the memory bitmap to a DIB by calling GetDIBits. To display the DIB to the second device,
call SetDIBits or StretchDIBits.
Examples
Requirements
StretchDIBits Function
The StretchDIBits function copies the color data for a rectangle of pixels in a DIB, JPEG, or
PNG image to the specified destination rectangle. If the destination rectangle is larger than
the source rectangle, this function stretches the rows and columns of color data to fit the
destination rectangle. If the destination rectangle is smaller than the source rectangle, this
function compresses the rows and columns by using the specified raster operation.
Syntax
Copy
int StretchDIBits(
__in HDC hdc,
__in int XDest,
__in int YDest,
__in int nDestWidth,
__in int nDestHeight,
__in int XSrc,
__in int YSrc,
__in int nSrcWidth,
__in int nSrcHeight,
__in const VOID *lpBits,
__in const BITMAPINFO *lpBitsInfo,
__in UINT iUsage,
__in DWORD dwRop
);
Parameters
hdc [in]
XDest [in]
The x-coordinate, in logical units, of the upper-left corner of the destination rectangle.
YDest [in]
The y-coordinate, in logical units, of the upper-left corner of the destination rectangle.
nDestWidth [in]
nDestHeight [in]
YSrc [in]
nSrcWidth [in]
nSrcHeight [in]
lpBits [in]
A pointer to the image bits, which are stored as an array of bytes. For more
information, see the Remarks section.
lpBitsInfo [in]
iUsage [in]
Value Meaning
The array contains 16-bit indexes into the logical palette of the
DIB_PAL_COLORS
source device context.
DIB_RGB_COLORS The color table contains literal RGB values.
dwRop [in]
Specifies how the source pixels, the destination device context's current brush, and the
destination pixels are to be combined to form the new image. For more information,
see the following Remarks section.
Return Value
If the function succeeds, the return value is the number of scan lines copied. Note that this
value can be negative for mirrored content.
If the function fails, or no scan lines are copied, the return value is 0.
If the driver cannot support the JPEG or PNG file image passed to StretchDIBits, the
function will fail and return GDI_ERROR. If failure does occur, the application must fall
back on its own JPEG or PNG support to decompress the image into a bitmap, and then pass
the bitmap to StretchDIBits.
Remarks
The origin of a bottom-up DIB is the bottom-left corner; the origin of a top-down DIB is the
upper-left corner.
StretchDIBits creates a mirror image of a bitmap if the signs of the nSrcWidth and
nDestWidth parameters, or if the nSrcHeight and nDestHeight parameters differ. If
nSrcWidth and nDestWidth have different signs, the function creates a mirror image of the
bitmap along the x-axis. If nSrcHeight and nDestHeight have different signs, the function
creates a mirror image of the bitmap along the y-axis.
This function allows a JPEG or PNG image to be passed as the source image. How each
parameter is used remains the same, except:
ICM: Color management is performed if color management has been enabled with a call to
SetICMMode with the iEnableICM parameter set to ICM_ON. If the bitmap specified by
lpBitsInfo has a BITMAPV4HEADER that specifies the gamma and endpoints members, or
a BITMAPV5HEADER that specifies either the gamma and endpoints members or the
profileData and profileSize members, then the call treats the bitmap's pixels as being
expressed in the color space described by those members, rather than in the device context's
source color space.
Examples
Requirements
d) SetViewportExtEx()
SetViewportExtEx Function
The SetViewportExtEx function sets the horizontal and vertical extents of the viewport for a
device context by using the specified values.
Syntax
Copy
BOOL SetViewportExtEx(
__in HDC hdc,
__in int nXExtent,
__in int nYExtent,
__out LPSIZE lpSize
);
Parameters
hdc [in]
nXExtent [in]
nYExtent [in]
lpSize [out]
A pointer to a SIZE structure that receives the previous viewport extents, in device
units. If lpSize is NULL, this parameter is not used.
Return Value
Remarks
The viewport refers to the device coordinate system of the device space. The extent is the
maximum value of an axis. This function sets the maximum values for the horizontal and
vertical axes of the viewport in device coordinates (or pixels). When mapping between page
space and device space, SetWindowExtEx and SetViewportExtEx determine the scaling
factor between the window and the viewport. For more information, see Transformation of
Coordinate Spaces.
When the following mapping modes are set, calls to the SetWindowExtEx and
SetViewportExtEx functions are ignored.
MM_HIENGLISH
MM_HIMETRIC
MM_LOENGLISH
MM_LOMETRIC
MM_TEXT
MM_TWIPS
Examples
Requirements
e) SetScrollInfo()
SetScrollInfo Function
The SetScrollInfo function sets the parameters of a scroll bar, including the minimum and
maximum scrolling positions, the page size, and the position of the scroll box (thumb). The
function also redraws the scroll bar, if requested.
Syntax
Copy
int SetScrollInfo(
__in HWND hwnd,
__in int fnBar,
__in LPCSCROLLINFO lpsi,
__in BOOL fRedraw
);
Parameters
hwnd [in]
HWND
Handle to a scroll bar control or a window with a standard scroll bar, depending on
the value of the fnBar parameter.
fnBar [in]
int
Specifies the type of scroll bar for which to set parameters. This parameter can be one
of the following values.
Value Meaning
Sets the parameters of a scroll bar control. The hwnd parameter must be
SB_CTL
the handle to the scroll bar control.
SB_HORZ Sets the parameters of the window's standard horizontal scroll bar.
SB_VERT Sets the parameters of the window's standard vertical scroll bar.
lpsi [in]
LPCSCROLLINFO
Value Meaning
Disables the scroll bar instead of removing it, if the scroll
SIF_DISABLENOSCROLL
bar's new parameters make the scroll bar unnecessary.
Sets the scroll page to the value specified in the nPage
SIF_PAGE member of the SCROLLINFO structure pointed to by
lpsi.
Sets the scroll position to the value specified in the nPos
SIF_POS member of the SCROLLINFO structure pointed to by
lpsi.
Sets the scroll range to the value specified in the nMin
SIF_RANGE and nMax members of the SCROLLINFO structure
pointed to by lpsi.
fRedraw [in]
BOOL
Specifies whether the scroll bar is redrawn to reflect the changes to the scroll bar. If
this parameter is TRUE, the scroll bar is redrawn, otherwise, it is not redrawn.
Return Value
int
Remarks
The SetScrollInfo function performs range checking on the values specified by the nPage
and nPos members of the SCROLLINFO structure. The nPage member must specify a
value from 0 to nMax - nMin +1. The nPos member must specify a value between nMin and
nMax - max( nPage– 1, 0). If either value is beyond its range, the function sets it to a value
that is just within the range.
If the fnBar parameter is SB_CTL and the window specified by the hwnd parameter is not a
system scroll bar control, the system sends the SBM_SETSCROLLINFO message to the
window to set scroll bar information (The system can optimize the message to
SBM_SETPOS or SBM_SETRANGE if the request is solely for the position or range). This
allows SetScrollInfo to operate on a custom control that mimics a scroll bar. If the window
does not handle SBM_SETSCROLLINFO (or the optimized SBM_SETPOS message or
SBM_SETRANGE message), then the SetScrollInfo function fails.
Requirements
f) CreateCompatibleDC()
CreateCompatibleDC Function
The CreateCompatibleDC function creates a memory device context (DC) compatible with
the specified device.
Syntax
Copy
HDC CreateCompatibleDC(
__in HDC hdc
);
Parameters
hdc [in]
A handle to an existing DC. If this handle is NULL, the function creates a memory
DC compatible with the application's current screen.
Return Value
If the function succeeds, the return value is the handle to a memory DC.
Remarks
A memory DC exists only in memory. When the memory DC is created, its display surface is
exactly one monochrome pixel wide and one monochrome pixel high. Before an application
can use a memory DC for drawing operations, it must select a bitmap of the correct width and
height into the DC. To select a bitmap into a DC, use the CreateCompatibleBitmap
function, specifying the height, width, and color organization required.
When a memory DC is created, all attributes are set to normal default values. The memory
DC can be used as a normal DC. You can set the attributes; obtain the current settings of its
attributes; and select pens, brushes, and regions.
The CreateCompatibleDC function can only be used with devices that support raster
operations. An application can determine whether a device supports these operations by
calling the GetDeviceCaps function.
When you no longer need the memory DC, call the DeleteDC function.
If hdc is NULL, the thread that calls CreateCompatibleDC owns the HDC that is created.
When this thread is destroyed, the HDC is no longer valid. Thus, if you create the HDC
andpass it to another thread, then exit the first thread, the second thread will not be able to use
the HDC.
ICM: If the DC that is passed to this function is enabled for Image Color Management
(ICM), the DC created by the function is ICM-enabled. The source and destination color
spaces are specified in the DC.
Examples
TranslateMessage Function
The TranslateMessage function translates virtual-key messages into character messages. The
character messages are posted to the calling thread's message queue, to be read the next time
the thread calls the GetMessage or PeekMessage function.
Syntax
Copy
BOOL TranslateMessage(
__in const MSG *lpMsg
);
Parameters
lpMsg [in]
MSG
Pointer to an MSG structure that contains message information retrieved from the
calling thread's message queue by using the GetMessage or PeekMessage function.
Return Value
BOOL
If the message is translated (that is, a character message is posted to the thread's message
queue), the return value is nonzero.
If the message is not translated (that is, a character message is not posted to the thread's
message queue), the return value is zero.
Remarks
The TranslateMessage function does not modify the message pointed to by the lpMsg
parameter.
TranslateMessage produces WM_CHAR messages only for keys that are mapped to ASCII
characters by the keyboard driver.
If applications process virtual-key messages for some other purpose, they should not call
TranslateMessage. For instance, an application should not call TranslateMessage if the
TranslateAccelerator function returns a nonzero value. Note that the application is
responsible for retrieving and dispatching input messages to the dialog box. Most
applications use the main message loop for this. However, to permit the user to move to and
to select controls by using the keyboard, the application must call IsDialogMessage. For
more information, see Dialog Box Keyboard Interface.
Examples
An optional entry point into a dynamic-link library (DLL). When the system starts or
terminates a process or thread, it calls the entry-point function for each loaded DLL using the
first thread of the process. The system also calls the entry-point function for a DLL when it is
loaded or unloaded using the LoadLibrary and FreeLibrary functions.
Warning There are serious limits on what you can do in a DLL entry point. To provide more
complex initialization, create an initialization routine for the DLL. You can require
applications to call the initialization routine before calling any other routines in the DLL.
Syntax
VB
C#
C++
F#
JScript
Copy
BOOL WINAPI DllMain(
__in HINSTANCE hinstDLL,
__in DWORD fdwReason,
__in LPVOID lpvReserved
);
Parameters
hinstDLL [in]
A handle to the DLL module. The value is the base address of the DLL. The
HINSTANCE of a DLL is the same as the HMODULE of the DLL, so hinstDLL can
be used in calls to functions that require a module handle.
fdwReason [in]
The reason code that indicates why the DLL entry-point function is being called. This
parameter can be one of the following values.
Value Meaning
The DLL is being loaded into the virtual address space of
the current process as a result of the process starting up or
as a result of a call to LoadLibrary. DLLs can use this
opportunity to initialize any instance data or to use the
DLL_PROCESS_ATTACH
TlsAlloc function to allocate a thread local storage (TLS)
1
index.
lpvReserved [in]
Return Value
When the system calls the DllMain function with the DLL_PROCESS_ATTACH value, the
function returns TRUE if it succeeds or FALSE if initialization fails. If the return value is
FALSE when DllMain is called because the process uses the LoadLibrary function,
LoadLibrary returns NULL. (The system immediately calls your entry-point function with
DLL_PROCESS_DETACH and unloads the DLL.) If the return value is FALSE when
DllMain is called during process initialization, the process terminates with an error. To get
extended error information, call GetLastError.
When the system calls the DllMain function with any value other than
DLL_PROCESS_ATTACH, the return value is ignored.
Remarks
DllMain is a placeholder for the library-defined function name. You must specify the actual
name you use when you build your DLL. For more information, see the documentation
included with your development tools.
During initial process startup or after a call to LoadLibrary, the system scans the list of
loaded DLLs for the process. For each DLL that has not already been called with the
DLL_PROCESS_ATTACH value, the system calls the DLL's entry-point function. This call
is made in the context of the thread that caused the process address space to change, such as
the primary thread of the process or the thread that called LoadLibrary. Access to the entry
point is serialized by the system on a process-wide basis. Threads in DllMain hold the loader
lock so no additional DLLs can be dynamically loaded or initialized.
There are cases in which the entry-point function is called for a terminating thread even if the
entry-point function was never called with DLL_THREAD_ATTACH for the thread:
The thread was the initial thread in the process, so the system called the entry-point
function with the DLL_PROCESS_ATTACH value.
The thread was already running when a call to the LoadLibrary function was made,
so the system never called the entry-point function for it.
When a DLL is unloaded from a process as a result of an unsuccessful load of the DLL,
termination of the process, or a call to FreeLibrary, the system does not call the DLL's
entry-point function with the DLL_THREAD_DETACH value for the individual threads of
the process. The DLL is only sent a DLL_PROCESS_DETACH notification. DLLs can take
this opportunity to clean up all resources for all threads known to the DLL.
Because Kernel32.dll is guaranteed to be loaded in the process address space when the entry-
point function is called, calling functions in Kernel32.dll does not result in the DLL being
used before its initialization code has been executed. Therefore, the entry-point function can
call functions in Kernel32.dll that do not load other DLLs. For example, DllMain can create
synchronization objects such as critical sections and mutexes, and use TLS. Unfortunately,
there is not a comprehensive list of safe functions in Kernel32.dll.
Calling functions that require DLLs other than Kernel32.dll may result in problems that are
difficult to diagnose. For example, calling User, Shell, and COM functions can cause access
violation errors, because some functions load other system components. Conversely, calling
functions such as these during termination can cause access violation errors because the
corresponding component may already have been unloaded or uninitialized.
Because DLL notifications are serialized, entry-point functions should not attempt to
communicate with other threads or processes. Deadlocks may occur as a result.
If your DLL is linked with the C run-time library (CRT), the entry point provided by the CRT
calls the constructors and destructors for global and static C++ objects. Therefore, these
restrictions for DllMain also apply to constructors and destructors and any code that is called
from them.
Examples
Requirements
15. CenterHorz() is a user defined function to center a given string in a given row on the client
area of a given
window. Its declaration is as follows -
void CenterHorz(HWND, int, char *);
Implement it.
16. Write the steps required to use accelerators in your application. *
17. How can you utilise the idle time of your application? Which portion of your code will you alter
to achieve this? Write the portion of the code, which will undergo change.
CreateThread()
CreateThread Function
Creates a thread to execute within the virtual address space of the calling process.
To create a thread that runs in the virtual address space of another process, use the
CreateRemoteThread function.
Syntax
VB
C#
C++
F#
JScript
Copy
HANDLE WINAPI CreateThread(
__in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
__in SIZE_T dwStackSize,
__in LPTHREAD_START_ROUTINE lpStartAddress,
__in_opt LPVOID lpParameter,
__in DWORD dwCreationFlags,
__out_opt LPDWORD lpThreadId
);
Parameters
The initial size of the stack, in bytes. The system rounds this value to the nearest page.
If this parameter is zero, the new thread uses the default size for the executable. For
more information, see Thread Stack Size.
lpStartAddress [in]
dwCreationFlags [in]
Value Meaning
0 The thread runs immediately after creation.
The thread is created in a suspended state,
CREATE_SUSPENDED
and does not run until the ResumeThread
0x00000004
function is called.
The dwStackSize parameter specifies the
initial reserve size of the stack. If this flag
is not specified, dwStackSize specifies the
STACK_SIZE_PARAM_IS_A_RESERV commit size.
ATION
0x00010000 Windows 2000: The
STACK_SIZE_PARAM_IS_A_RESERV
ATION flag is not supported.
A pointer to a variable that receives the thread identifier. If this parameter is NULL,
the thread identifier is not returned.
Return Value
If the function succeeds, the return value is a handle to the new thread.
If the function fails, the return value is NULL. To get extended error information, call
GetLastError.
Note that CreateThread may succeed even if lpStartAddress points to data, code, or is not
accessible. If the start address is invalid when the thread runs, an exception occurs, and the
thread terminates. Thread termination due to a invalid start address is handled as an error exit
for the thread's process. This behavior is similar to the asynchronous nature of
CreateProcess, where the process is created even if it refers to invalid or missing dynamic-
link libraries (DLLs).
Remarks
The number of threads a process can create is limited by the available virtual memory. By
default, every thread has one megabyte of stack space. Therefore, you can create at most
2,048 threads. If you reduce the default stack size, you can create more threads. However,
your application will have better performance if you create one thread per processor and build
queues of requests for which the application maintains the context information. A thread
would process all requests in a queue before processing requests in the next queue.
The new thread handle is created with the THREAD_ALL_ACCESS access right. If a
security descriptor is not provided when the thread is created, a default security descriptor is
constructed for the new thread using the primary token of the process that is creating the
thread. When a caller attempts to access the thread with the OpenThread function, the
effective token of the caller is evaluated against this security descriptor to grant or deny
access.
The newly created thread has full access rights to itself when calling the GetCurrentThread
function.
The thread execution begins at the function specified by the lpStartAddress parameter. If this
function returns, the DWORD return value is used to terminate the thread in an implicit call
to the ExitThread function. Use the GetExitCodeThread function to get the thread's return
value.
The thread is created with a thread priority of THREAD_PRIORITY_NORMAL. Use the
GetThreadPriority and SetThreadPriority functions to get and set the priority value of a
thread.
When a thread terminates, the thread object attains a signaled state, satisfying any threads that
were waiting on the object.
The thread object remains in the system until the thread has terminated and all handles to it
have been closed through a call to CloseHandle.
During process startup and DLL initialization routines, new threads can be created,
but they do not begin execution until DLL initialization is done for the process.
Only one thread in a process can be in a DLL initialization or detach routine at a time.
ExitProcess does not complete until there are no threads in their DLL initialization or
detach routines.
A thread in an executable that calls the C run-time library (CRT) should use the
_beginthreadex and _endthreadex functions for thread management rather than
CreateThread and ExitThread; this requires the use of the multi-threaded version of the
CRT. If a thread created using CreateThread calls the CRT, the CRT may terminate the
process in low-memory conditions.
Examples
Requirements
20. Explain with example the purpose and use of the following APIs/structures/messages:
a. SetDIBitsToDevice()
SetDIBitsToDevice Function
The SetDIBitsToDevice function sets the pixels in the specified rectangle on the device that
is associated with the destination device context using color data from a DIB, JPEG, or PNG
image.
Syntax
Copy
int SetDIBitsToDevice(
__in HDC hdc,
__in int XDest,
__in int YDest,
__in DWORD dwWidth,
__in DWORD dwHeight,
__in int XSrc,
__in int YSrc,
__in UINT uStartScan,
__in UINT cScanLines,
__in const VOID *lpvBits,
__in const BITMAPINFO *lpbmi,
__in UINT fuColorUse
);
Parameters
hdc [in]
XDest [in]
The x-coordinate, in logical units, of the upper-left corner of the destination rectangle.
YDest [in]
The y-coordinate, in logical units, of the upper-left corner of the destination rectangle.
dwWidth [in]
dwHeight [in]
XSrc [in]
YSrc [in]
cScanLines [in]
The number of DIB scan lines contained in the array pointed to by the lpvBits
parameter.
lpvBits [in]
A pointer to the color data stored as an array of bytes. For more information, see the
following Remarks section.
lpbmi [in]
fuColorUse [in]
Value Meaning
The color table consists of an array of 16-bit indexes into the
DIB_PAL_COLORS
currently selected logical palette.
DIB_RGB_COLORS The color table contains literal RGB values.
Return Value
If the function succeeds, the return value is the number of scan lines set.
If zero scan lines are set (such as when dwHeight is 0) or the function fails, the function
returns zero.
If the driver cannot support the JPEG or PNG file image passed to SetDIBitsToDevice, the
function will fail and return GDI_ERROR. If failure does occur, the application must fall
back on its own JPEG or PNG support to decompress the image into a bitmap, and then pass
the bitmap to SetDIBitsToDevice.
Remarks
Optimal bitmap drawing speed is obtained when the bitmap bits are indexes into the system
palette.
Applications can retrieve the system palette colors and indexes by calling the
GetSystemPaletteEntries function. After the colors and indexes are retrieved, the
application can create the DIB. For more information about the system palette, see Colors.
The scan lines must be aligned on a DWORD except for RLE-compressed bitmaps.
The origin of a bottom-up DIB is the lower-left corner of the bitmap; the origin of a top-down
DIB is the upper-left corner.
To reduce the amount of memory required to set bits from a large DIB on a device surface, an
application can band the output by repeatedly calling SetDIBitsToDevice, placing a different
portion of the bitmap into the lpvBits array each time. The values of the uStartScan and
cScanLines parameters identify the portion of the bitmap contained in the lpvBits array.
ICM: Color management is performed if color management has been enabled with a call to
SetICMMode with the iEnableICM parameter set to ICM_ON. If the bitmap specified by
lpbmi has a BITMAPV4HEADER that specifies the gamma and endpoints members, or a
BITMAPV5HEADER that specifies either the gamma and endpoints members or the
profileData and profileSize members, then the call treats the bitmap's pixels as being
expressed in the color space described by those members, rather than in the device context's
source color space.
Examples
Requirements
Syntax
VB
C#
C++
F#
JScript
Copy
void WINAPI DeleteCriticalSection(
__inout LPCRITICAL_SECTION lpCriticalSection
);
Parameters
A pointer to the critical section object. The object must have been previously
initialized with the InitializeCriticalSection function.
Return Value
Remarks
Deleting a critical section object releases all system resources used by the object.
After a critical section object has been deleted, do not reference the object in any function
that operates on critical sections (such as EnterCriticalSection, TryEnterCriticalSection,
and LeaveCriticalSection) other than InitializeCriticalSection and
InitializeCriticalSectionAndSpinCount. If you attempt to do so, memory corruption and
other unexpected errors can occur.
If a critical section is deleted while it is still owned, the state of the threads waiting for
ownership of the deleted critical section is undefined.
Examples
For an example that uses DeleteCriticalSection, see Using Critical Section Objects.
Requirements
EnterCriticalSection Function
Waits for ownership of the specified critical section object. The function returns when the
calling thread is granted ownership.
Syntax
VB
C#
C++
F#
JScript
Copy
void WINAPI EnterCriticalSection(
__inout LPCRITICAL_SECTION lpCriticalSection
);
Parameters
Return Value
Remarks
The threads of a single process can use a critical section object for mutual-exclusion
synchronization. The process is responsible for allocating the memory used by a critical
section object, which it can do by declaring a variable of type CRITICAL_SECTION.
Before using a critical section, some thread of the process must call InitializeCriticalSection
or InitializeCriticalSectionAndSpinCount to initialize the object.
To enable mutually exclusive access to a shared resource, each thread calls the
EnterCriticalSection or TryEnterCriticalSection function to request ownership of the
critical section before executing any section of code that accesses the protected resource. The
difference is that TryEnterCriticalSection returns immediately, regardless of whether it
obtained ownership of the critical section, while EnterCriticalSection blocks until the thread
can take ownership of the critical section. When it has finished executing the protected code,
the thread uses the LeaveCriticalSection function to relinquish ownership, enabling another
thread to become owner and access the protected resource. There is no guarantee about the
order in which waiting threads will acquire ownership of the critical section.
After a thread has ownership of a critical section, it can make additional calls to
EnterCriticalSection or TryEnterCriticalSection without blocking its execution. This
prevents a thread from deadlocking itself while waiting for a critical section that it already
owns. The thread enters the critical section each time EnterCriticalSection and
TryEnterCriticalSection succeed. A thread must call LeaveCriticalSection once for each
time that it entered the critical section.
Any thread of the process can use the DeleteCriticalSection function to release the system
resources that were allocated when the critical section object was initialized. After this
function has been called, the critical section object can no longer be used for synchronization.
If a thread terminates while it has ownership of a critical section, the state of the critical
section is undefined.
If a critical section is deleted while it is still owned, the state of the threads waiting for
ownership of the deleted critical section is undefined.
Examples
For an example that uses EnterCriticalSection, see Using Critical Section Objects.
Requirements
c. WaitForMultipleObjects()
WaitForMultipleObjects Function
Waits until one or all of the specified objects are in the signaled state or the time-out interval
elapses.
Syntax
VB
C#
C++
F#
JScript
Copy
DWORD WINAPI WaitForMultipleObjects(
__in DWORD nCount,
__in const HANDLE *lpHandles,
__in BOOL bWaitAll,
__in DWORD dwMilliseconds
);
Parameters
nCount [in]
The number of object handles in the array pointed to by lpHandles. The maximum
number of object handles is MAXIMUM_WAIT_OBJECTS.
lpHandles [in]
An array of object handles. For a list of the object types whose handles can be
specified, see the following Remarks section. The array can contain handles to objects
of different types. It may not contain multiple copies of the same handle.
If one of these handles is closed while the wait is still pending, the function's behavior
is undefined.
The handles must have the SYNCHRONIZE access right. For more information, see
Standard Access Rights.
bWaitAll [in]
If this parameter is TRUE, the function returns when the state of all objects in the
lpHandles array is signaled. If FALSE, the function returns when the state of any one
of the objects is set to signaled. In the latter case, the return value indicates the object
whose state caused the function to return.
dwMilliseconds [in]
Return Value
If the function succeeds, the return value indicates the event that caused the function to
return. It can be one of the following values. (Note that WAIT_OBJECT_0 is defined as 0
and WAIT_ABANDONED_0 is defined as 0x00000080L.)
Remarks
The WaitForMultipleObjects function determines whether the wait criteria have been met.
If the criteria have not been met, the calling thread enters the wait state until the conditions of
the wait criteria have been met or the time-out interval elapses.
When bWaitAll is TRUE, the function's wait operation is completed only when the states of
all objects have been set to signaled. The function does not modify the states of the specified
objects until the states of all objects have been set to signaled. For example, a mutex can be
signaled, but the thread does not get ownership until the states of the other objects are also set
to signaled. In the meantime, some other thread may get ownership of the mutex, thereby
setting its state to nonsignaled.
When bWaitAll is FALSE, this function checks the handles in the array in order starting with
index 0, until one of the objects is signaled. If multiple objects become signaled, the function
returns the index of the first handle in the array whose object was signaled.
The function modifies the state of some types of synchronization objects. Modification
occurs only for the object or objects whose signaled state caused the function to return. For
example, the count of a semaphore object is decreased by one. For more information, see the
documentation for the individual synchronization objects.
The WaitForMultipleObjects function can specify handles of any of the following object
types in the lpHandles array:
Change notification
Console input
Event
Memory resource notification
Mutex
Process
Semaphore
Thread
Waitable timer
Use caution when calling the wait functions and code that directly or indirectly creates
windows. If a thread creates any windows, it must process messages. Message broadcasts are
sent to all windows in the system. A thread that uses a wait function with no time-out interval
may cause the system to become deadlocked. Two examples of code that indirectly creates
windows are DDE and the CoInitialize function. Therefore, if you have a thread that creates
windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather
than WaitForMultipleObjects.
Examples
The following example uses the CreateEvent function to create two event objects and the
CreateThread function to create a thread. It then uses the WaitForMultipleObjects
function to wait for the thread to set the state of one of the objects to signaled using the
SetEvent function.
For an example that waits for a single object, see Using Mutex Objects.
Copy
#include <windows.h>
#include <stdio.h>
HANDLE ghEvents[2];
void main()
{
HANDLE hThread;
DWORD i, dwEvent, dwThreadID;
if (ghEvents[i] == NULL)
{
printf("CreateEvent error: %d\n", GetLastError() );
ExitProcess(0);
}
}
// Create a thread
hThread = CreateThread(
NULL, // default security attributes
0, // default stack size
(LPTHREAD_START_ROUTINE) ThreadProc,
NULL, // no thread function arguments
0, // default creation flags
&dwThreadID); // receive thread identifier
dwEvent = WaitForMultipleObjects(
2, // number of objects in array
ghEvents, // array of objects
FALSE, // wait for any object
5000); // five-second wait
switch (dwEvent)
{
// ghEvents[0] was signaled
case WAIT_OBJECT_0 + 0:
// TODO: Perform tasks required by this event
printf("First event was signaled.\n");
break;
case WAIT_TIMEOUT:
printf("Wait timed out.\n");
break;
if ( !SetEvent(ghEvents[0]) )
{
printf("SetEvent failed (%d)\n", GetLastError());
return -1;
}
return 1;
}
d. NMHDR
NMHDR Structure
Contains information about a notification message.
Syntax
Copy
typedef struct tagNMHDR {
HWND hwndFrom;
UINT_PTR idFrom;
UINT code;
} NMHDR;
Members
hwndFrom
HWND
idFrom
UINT_PTR
code
UINT
A notification code. This member can be one of the common notification codes (see
Notifications under General Control Reference), or it can be a control-specific
notification code.
Requirements
e. WM_RENDERFORMAT
WM_RENDERFORMAT Message
wParam
lParam
Return Value
Remarks
Requirements