Sunday, June 14, 2009

Difference between a Model and a Modeless Dialog

Working with modeless dialog boxes is similar to working with modal dialog boxes, but there are several important differences.

First, modeless dialog boxes usually include a caption bar and a system menu box. These are actually the default options when you create a dialog box in Developer Studio. The STYLE statement in the dialog box template for a modeless dialog box will look something like this:
STYLE WS_POPUP ¦ WS_CAPTION ¦ WS_SYSMENU ¦ WS_VISIBLE
The caption bar and system menu allow the user to move the modeless dialog box to another area of the display using either the mouse or the keyboard. You don't normally provide a caption bar and system menu with a modal dialog box, because the user can't do anything in the underlying window anyway.

The second big difference: Notice that the WS_VISIBLE style is included in our sample STYLE statement. In Developer Studio, select this option from the More Styles tab of the Dialog Properties dialog. If you omit WS_VISIBLE, you must call ShowWindow after the CreateDialog call:
hDlgModeless = CreateDialog ( . . . ) ;
ShowWindow (hDlgModeless, SW_SHOW) ;
If you neither include WS_VISIBLE nor call ShowWindow, the modeless dialog box will not be displayed. Programmers who have mastered modal dialog boxes often overlook this peculiarity and thus experience difficulties when first trying to create a modeless dialog box.

The third difference: Unlike messages to modal dialog boxes and message boxes, messages to modeless dialog boxes come through your program's message queue. The message queue must be altered to pass these messages to the dialog box window procedure. Here's how you do it: When you use CreateDialog to create a modeless dialog box, you should save the dialog box handle returned from the call in a global variable (for instance, hDlgModeless). Change your message loop to look like
while (GetMessage (&msg, NULL, 0, 0))
{
if (hDlgModeless == 0 ¦¦ !IsDialogMessage (hDlgModeless, &msg))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
If the message is intended for the modeless dialog box, then IsDialogMessage sends it to the dialog box window procedure and returns TRUE (nonzero); otherwise, it returns FALSE (0). The TranslateMessage and DispatchMessage functions should be called only if hDlgModeless is 0 or if the message is not for the dialog box. If you use keyboard accelerators for your program's window, the message loop looks like this:
while (GetMessage (&msg, NULL, 0, 0))
{
if (hDlgModeless == 0 ¦¦ !IsDialogMessage (hDlgModeless, &msg))
{
if (!TranslateAccelerator (hwnd, hAccel, &msg))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
}
Because global variables are initialized to 0, hDlgModeless will be 0 until the dialog box is created, thus ensuring that IsDialogMessage is not called with an invalid window handle. You must take the same precaution when you destroy the modeless dialog box, as explained below.
The hDlgModeless variable can also be used by other parts of the program as a test of the existence of the modeless dialog box. For example, other windows in the program can send messages to the dialog box while hDlgModeless is not equal to 0.
The final big difference: Use DestroyWindow rather than EndDialog to end a modeless dialog box. When you call DestroyWindow, set the hDlgModeless global variable to NULL.
The user customarily terminates a modeless dialog box by choosing Close from the system menu. Although the Close option is enabled, the dialog box window procedure within Windows does not process the WM_CLOSE message. You must do this yourself in the dialog box procedure:
case WM_CLOSE :
DestroyWindow (hDlg) ;
hDlgModeless = NULL ;
break ;
Note the difference between these two window handles: the hDlg parameter to DestroyWindow is the parameter passed to the dialog box procedure; hDlgModeless is the global variable returned from CreateDialog that you test within the message loop.
You can also allow a user to close a modeless dialog box using push buttons. Use the same logic as for the WM_CLOSE message. Any information that the dialog box must "return" to the window that created it can be stored in global variables. If you'd prefer not using global variables, you can create the modeless dialog box by using CreateDialogParam and pass to it a structure pointer, as described earlier.

Difference between a struct and a class

This is a common question in an interviews. Mostly an interviewer asks about the difference between a struct and a class ? In c++, difference is that struct has by-default public access to data-members and a class has by-default private access to data-members. And inheritance is by default public in case of a struct and private in case of a class. That is it!
Interviewer asks, 'What else?'
Above differences looks sufficient, but, there is more that interviewer expects. What is that ?

We cannot have,
template <\struct type\> /* ignore slash */
struct ABC{...};

Like,
template <\class type\> /* ignore slash */
class ABC{...};
Because templates do not offer backward C compatibilty.

He asks again, 'What else ?' { still more expecting ?...}
The use of one-element array at the end of a struct to allow individual struct objects to address variable-size array:
strcut ABC
{
int s;
char arr[1];
};

struct ABC* pAbc = (struct ABC*)malloc(sizeof(struct ABC)+strlen(string)+1);
strcpy(pAbc->arr, string);
This may or may nto translate well when placed within a class declaration that specifies multiple access sections containing data, derives from another class, or defines virtual functions.

Otherwise, struct is same as class... struct offers virtual functions, inheritance, ctor-dtor..everything what class offers.