2025-11-28 00:35:46 +09:00

860 lines
24 KiB
C++

// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <strsafe.h>
#include "resource.h"
#include "appbar.h"
//////////////////////////////////////////////////////////////////////////////
// Local prototypes
BOOL Main_OnCreate(HWND, LPCREATESTRUCT);
void Main_OnActivate(HWND, UINT, HWND, BOOL);
void Main_OnWindowPosChanged(HWND, const LPWINDOWPOS);
void Main_OnCommand(HWND, int, HWND, UINT);
void Main_OnSize(HWND, UINT, int, int);
void Main_OnMove(HWND, int, int);
void Main_OnRButtonUp(HWND, int, int, UINT);
void Main_OnDestroy(HWND);
void Main_OnTimer(HWND, UINT);
UINT Main_OnNCHitTest(HWND, int, int);
void Main_OnPaint(HWND);
void Main_OnLButtonUp(HWND hwnd, int x, int y, UINT keyFlags);
void Main_OnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags);
void Main_OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags);
INT_PTR CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM);
//////////////////////////////////////////////////////////////////////////////
// Global Variables
static HFONT s_hFontTop, s_hFontLeft;
static BOOL s_fMoving = FALSE;
static RECT s_rcDrag;
//
// FUNCTION: MainWndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main application window.
//
// PARAMETERS:
// hwnd - handle the the window receiving the message
// uMsg - identifier of the message
// wParam - additional info associated with the message
// lParam - additional info associated with the message
//
// RETURN VALUE:
// (LRESULT) Returns 0 by default if the message is handled by this
// procedure.
//
LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT lResult = 0;
switch(uMsg)
{
HANDLE_MSG(hwnd, WM_CREATE, Main_OnCreate);
HANDLE_MSG(hwnd, WM_ACTIVATE, Main_OnActivate);
HANDLE_MSG(hwnd, WM_WINDOWPOSCHANGED, Main_OnWindowPosChanged);
HANDLE_MSG(hwnd, WM_COMMAND, Main_OnCommand);
HANDLE_MSG(hwnd, WM_SIZE, Main_OnSize);
HANDLE_MSG(hwnd, WM_MOVE, Main_OnMove);
HANDLE_MSG(hwnd, WM_RBUTTONUP, Main_OnRButtonUp);
HANDLE_MSG(hwnd, WM_DESTROY, Main_OnDestroy);
HANDLE_MSG(hwnd, WM_TIMER, Main_OnTimer);
HANDLE_MSG(hwnd, WM_NCHITTEST, Main_OnNCHitTest);
HANDLE_MSG(hwnd, WM_PAINT, Main_OnPaint);
HANDLE_MSG(hwnd, WM_LBUTTONDOWN, Main_OnLButtonDown);
HANDLE_MSG(hwnd, WM_MOUSEMOVE, Main_OnMouseMove);
HANDLE_MSG(hwnd, WM_LBUTTONUP, Main_OnLButtonUp);
case APPBAR_CALLBACK:
AppBar_Callback(hwnd, uMsg, wParam, lParam);
lResult = 0;
break;
default: // Pass message on for default proccessing
lResult = DefWindowProc( hwnd, uMsg, wParam, lParam );
break;
}
// If we performed non-default processing on the message, return FALSE
return lResult;
}
//
// FUNCTION: Main_OnCreate(HWND, LPCREATESTRUCT)
//
// PURPOSE: Handles any window initialization for this window class.
//
// PARAMETERS:
// hwnd - Handle of the window being created.
// lpCreateStruct - Pointer to the data used to create this window.
//
// RETURN VALUE:
// Returns TRUE to allow the window to be created, FALSE otherwise.
//
BOOL Main_OnCreate(HWND hwnd, LPCREATESTRUCT /* lpCreateStruct */)
{
// Initialize the common control DLL
InitCommonControls();
// Allocate an OPTIONS struct and attach to the appbar
POPTIONS pOptions = (POPTIONS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(OPTIONS));
if (pOptions)
{
SetWindowLongPtr(hwnd, 0,(LONG_PTR)pOptions);
}
else
{
return FALSE;
}
pOptions->fAutoHide = FALSE;
pOptions->fOnTop = FALSE;
pOptions->uSide = ABE_TOP;
pOptions->cxWidth = CX_DEFWIDTH;
pOptions->cyHeight = CY_DEFHEIGHT;
// Register the appbar and attach it to the top by default
AppBar_Register(hwnd);
AppBar_SetSide(hwnd, ABE_TOP);
// Create the fonts for drawing in the client area
LOGFONT lf;
ZeroMemory(&lf,sizeof(LOGFONT));
lf.lfHeight = 45;
lf.lfEscapement = 2700;
lf.lfOrientation = 0;
StringCchCopy(lf.lfFaceName, ARRAYSIZE(lf.lfFaceName), L"Arial");
s_hFontLeft = CreateFontIndirect(&lf);
lf.lfEscapement = 0;
s_hFontTop = CreateFontIndirect(&lf);
return TRUE;
}
//
// FUNCTION: Main_OnActivate(HWND, UINT, HWND, BOOL)
//
// PURPOSE: Handles hiding and showing of the appbar if it has the autohide
// state set.
//
// PARAMETERS:
// hwnd - Handle of the window receiving the message.
// state - Specifies whether the winodw is being activated or
// deactivated.
// hwndActDeact - Identifies the window being activated or deactivated,
// depending on the state parameter.
// fMinimized - A nonzero value indicates the window is minmized.
//
void Main_OnActivate(HWND hwnd, UINT state, HWND /* hwndActDeact */, BOOL /* fMinimized */)
{
APPBARDATA abd;
// Always send the activate message to the system
abd.cbSize = sizeof(APPBARDATA);
abd.hWnd = hwnd;
abd.lParam = 0;
SHAppBarMessage(ABM_ACTIVATE, &abd);
// Now determine if we're getting or losing activation
switch (state)
{
case WA_ACTIVE:
case WA_CLICKACTIVE:
// If we're gaining activation, make sure we're visible
AppBar_UnHide(hwnd);
KillTimer(hwnd, IDT_AUTOHIDE);
break;
case WA_INACTIVE:
// If we're losing activation, check to see if we need to autohide.
AppBar_Hide(hwnd);
break;
}
}
//
// FUNCTION: Main_OnWindowPosChanged(HWND, const LPWINDOWPOS)
//
// PURPOSE: Notifies the system that the appbar has changed position.
//
// PARAMETERS:
// hwnd - Handle of the appbar window receiving the message
// lpwpos - Pointer to a WINDOWPOS struct containing information about
// the new window position.
//
void Main_OnWindowPosChanged(HWND hwnd, const LPWINDOWPOS lpwpos)
{
APPBARDATA abd;
abd.cbSize = sizeof(APPBARDATA);
abd.hWnd = hwnd;
abd.lParam = 0;
SHAppBarMessage(ABM_WINDOWPOSCHANGED, &abd);
// DefWindowProc needs this to generate the WM_SIZE message.
FORWARD_WM_WINDOWPOSCHANGED(hwnd, lpwpos, DefWindowProc);
}
//
// FUNCTION: Main_OnCommand(HWND, int, HWND, UINT)
//
// PURPOSE: Handles the WM_COMMAND messages for the Win32Generic window
// class
//
// PARAMETERS:
// hwnd - handle of the window receiving the message
// id - identifier of the command
// hwndCtl - handle of the control sending the message)
// codeNotify - specifies the notification code if the message is from
// a control
//
// RETURN VALUE:
// none
//
// COMMENTS:
// codeNotify is 1 if from an accelerator, 0 if from a menu.
// If the message is not from a control hwndCtl is NULL.
//
void Main_OnCommand(HWND hwnd, int id, HWND /* hwndCtl */, UINT /* codeNotify */)
{
switch (id)
{
case ID_FILE_EXIT:
// The user wants to exit, so send our window a close message
SendMessage(hwnd, WM_CLOSE, 0, 0L);
break;
case ID_HELP_ABOUT:
// Display the "About" dialog
DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_ABOUT), hwnd, AboutDlgProc);
break;
case ID_PROPERTIES:
ShowOptions(hwnd);
break;
case ID_APPBAR_REGISTER:
AppBar_Register(hwnd);
break;
case ID_APPBAR_UNREGISTER:
AppBar_UnRegister(hwnd);
break;
case ID_APPBAR_AUTOHIDE:
AppBar_SetAutoHide(hwnd, TRUE);
break;
case ID_APPBAR_NOAUTOHIDE:
AppBar_SetAutoHide(hwnd, FALSE);
break;
case ID_APPBAR_TOP:
AppBar_SetSide(hwnd, ABE_TOP);
break;
case ID_APPBAR_BOTTOM:
AppBar_SetSide(hwnd, ABE_BOTTOM);
break;
case ID_APPBAR_LEFT:
AppBar_SetSide(hwnd, ABE_LEFT);
break;
case ID_APPBAR_RIGHT:
AppBar_SetSide(hwnd, ABE_RIGHT);
break;
}
}
//
// FUNCTION: Main_OnSize(HWND, UINT, int, int)
//
// PURPOSE: Notifies the system the appbar size has changed and updates the
// width and height stored in the OPTIONS struct.
//
// PARAMETERS:
// hwnd - Handle of the appbar window receiving the message.
// state - Determines the type of sizing that occured.
// cx - New width of the client area.
// cy - New height of the client area.
//
// COMMENTS:
// TODO: If the client rect size is zero and the bar is on the top or
// right, then the user will not be able to resize the window
void Main_OnSize(HWND hwnd, UINT /* state */, int /* cx */, int /* cy */)
{
POPTIONS pOpt = GetAppbarData(hwnd);
RECT rcWindow;
if (s_fMoving || pOpt->fAutoHide)
{
return;
}
// Let the system know the appbar size has changed
AppBar_Size(hwnd);
// Update the stored height and widths if the appbar is not hidden
if (!pOpt->fHiding)
{
GetWindowRect(hwnd, &rcWindow);
if (pOpt->uSide == ABE_TOP || pOpt->uSide == ABE_BOTTOM)
{
pOpt->cyHeight = rcWindow.bottom - rcWindow.top;
}
else
{
pOpt->cxWidth = rcWindow.right - rcWindow.left;
}
}
}
//
// FUNCTION: Main_OnMove(HWND, int, int)
//
// PURPOSE: Notifies the system the appbar has moved.
//
// PARAMETERS:
// hwnd - Handle of the appbar window receiving the message.
// x - New x-coordinate of the upper left corner of the client area
// y - New y-coordinate of the upper left corner of the client area
//
void Main_OnMove(HWND hwnd, int /* x */, int /* y */)
{
POPTIONS pOpt = GetAppbarData(hwnd);
if (s_fMoving || pOpt->fAutoHide)
{
return;
}
AppBar_Size(hwnd);
}
//
// FUNCTION: Main_OnRButtonUp(HWND, int, int, UINT)
//
// PURPOSE: Displays the context menu for the appbar.
//
// PARAMETERS:
// hwnd - Handle of the window receiving this message.
// x, y - Position of the mouse in client coordinates.
// keyFlags - State of the keyboard when the mouse button was pressed.
//
//
void Main_OnRButtonUp(HWND hwnd, int x, int y, UINT /* keyFlags */)
{
HMENU hMenu, hSubMenu;
POINT pt = {x, y};
MENUITEMINFO mii;
POPTIONS pOptions = GetAppbarData(hwnd);
UINT uItem;
TCHAR szMenu[64];
// Bring up the context menu
hMenu = LoadMenu(g_hInstance, MAKEINTRESOURCE(IDR_CONTEXTMENU));
hSubMenu = GetSubMenu(hMenu, 0);
// Convert the mouse position to screen coordinates
ClientToScreen(hwnd, &pt);
// Set the default menu item
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_STATE;
mii.fState = MFS_DEFAULT;
SetMenuItemInfo(hSubMenu, ID_PROPERTIES, FALSE, &mii);
// Set the radio button to the side we're on
if (ABE_TOP == pOptions->uSide)
{
uItem = ID_APPBAR_TOP;
}
else if (ABE_BOTTOM == pOptions->uSide)
{
uItem = ID_APPBAR_BOTTOM;
}
else if (ABE_LEFT == pOptions->uSide)
{
uItem = ID_APPBAR_LEFT;
}
else
{
uItem = ID_APPBAR_RIGHT;
}
mii.fMask = MIIM_TYPE | MIIM_STATE;
(LPTSTR) mii.dwTypeData = szMenu;
mii.cch = sizeof(szMenu);
GetMenuItemInfo(hSubMenu, uItem, FALSE, &mii);
mii.fType |= MFT_RADIOCHECK;
mii.fState = MFS_CHECKED;
SetMenuItemInfo(hSubMenu, uItem, FALSE, &mii);
// Display the menu
TrackPopupMenu(hSubMenu, TPM_RIGHTBUTTON, pt.x, pt.y, 0, hwnd, NULL);
}
//
// FUNCTION: Main_OnDestroy(HWND)
//
// PURPOSE: Handle any clean up and post the quit message to exit the
// message loop.
//
// PARAMETERS:
// hwnd - handle of the window receiving this message
//
void Main_OnDestroy(HWND hwnd)
{
POPTIONS pOptions = GetAppbarData(hwnd);
// Make sure the appbar is unregistered
if (g_fAppRegistered)
{
SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(ID_APPBAR_UNREGISTER, 0), 0L);
}
// Free the OPTIONS struct associated with the appbar
HeapFree(GetProcessHeap(), 0, pOptions);
// Clean up the GDI objects we allocated
DeleteObject(s_hFontTop);
DeleteObject(s_hFontLeft);
// Indicate that the message loop should exit since the main window
// is being destroyed.
PostQuitMessage(0);
}
//
// FUNCTION: Main_OnTimer(HWND, UINT)
//
// PURPOSE: Handles timer messages to either delay the showing or hiding
// of an appbar with the autohide state set.
//
// PARAMETERS:
// hwnd - Handle of the window receiving the timer.
// id - ID of the timer message.
//
void Main_OnTimer(HWND hwnd, UINT id)
{
POPTIONS pOpt = GetAppbarData(hwnd);
switch (id)
{
// The AUTOHIDE timer has fired. Check to see if the mouse is over our
// window and if not hide the appbar.
case IDT_AUTOHIDE:
if ((pOpt->fAutoHide) && (!pOpt->fHiding))
{
// Get the mouse position, the window position, and active window
POINT pt;
GetCursorPos(&pt);
RECT rc;
GetWindowRect(hwnd, &rc);
HWND hwndActive = GetForegroundWindow();
// If the mouse is outside of our window, or we are not active,
// or at least one window is active, or we are not the parent
// of an active window, the hide the appbar window.
if ((!PtInRect(&rc, pt)) && (hwndActive != hwnd) &&
(hwndActive != NULL) && (GetWindowOwner(hwndActive) != hwnd))
{
KillTimer(hwnd, id);
AppBar_Hide(hwnd);
}
}
break;
// The period between the time the user has entered our window and the
// time we should show the window has expired.
case IDT_AUTOUNHIDE:
{
// Kill the timer, we only need it to fire once.
KillTimer(hwnd, id);
if ((pOpt->fAutoHide) && (pOpt->fHiding))
{
// Check to see if the cursor is still in the appbar. If so,
// the unhide the window.
POINT pt;
GetCursorPos(&pt);
RECT rc;
GetWindowRect(hwnd, &rc);
if (PtInRect(&rc, pt))
{
AppBar_UnHide(hwnd);
}
}
break;
}
}
}
//
// FUNCTION: Main_OnNCHitTest(HWND, int, int)
//
// PURPOSE: Determines if we're over an edge that is resizable and also
// starts the window unhiding process.
//
// PARAMETERS:
// hwnd - Handle of the window receiving this message.
// x, y - Position of the mouse in screen coordinates.
//
// RETURN VALUE:
// Returns a constant denoting what part of the window the mouse is over.
// If the mouse is over a resizing border that is not on the inside of the
// screen, the function returns HTCLIENT to prevent the user from being
// able to resize the window in this direction.
//
UINT Main_OnNCHitTest(HWND hwnd, int x, int y)
{
POPTIONS pOpt = GetAppbarData(hwnd);
LRESULT lHitTest;
// Take care of the autohide stuff if needed
AppBar_SetAutoUnhideTimer(hwnd);
// Let DefWindowProc() tell us where the mouse is
lHitTest = FORWARD_WM_NCHITTEST(hwnd, x, y, DefWindowProc);
// We want to disable sizing in all directions except the inside edge.
if ((pOpt->uSide == ABE_TOP) && (lHitTest == HTBOTTOM))
{
return HTBOTTOM;
}
if ((pOpt->uSide == ABE_BOTTOM) && (lHitTest == HTTOP))
{
return HTTOP;
}
if ((pOpt->uSide == ABE_LEFT) && (lHitTest == HTRIGHT))
{
return HTRIGHT;
}
if ((pOpt->uSide == ABE_RIGHT) && (lHitTest == HTLEFT))
{
return HTLEFT;
}
return HTCLIENT;
}
//
// FUNCTION: Main_OnPaint
//
// PURPOSE: Displays a message in the AppBar client area
//
// PARAMETERS:
// hwnd - Handle of the window receiving the message.
//
void Main_OnPaint(HWND hwnd)
{
POPTIONS pOpt = GetAppbarData(hwnd);
HFONT hfont = NULL;
int x = 0, y = 0;
// Get the client rect
RECT rc;
GetClientRect(hwnd, &rc);
InvalidateRect(hwnd, NULL, TRUE);
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
// Figure out which side we're on so we can adjust the text accordingly
switch (pOpt->uSide)
{
case ABE_TOP:
case ABE_BOTTOM:
hfont = (HFONT)SelectObject(hdc, s_hFontTop);
x = 2;
y = 2;
break;
case ABE_LEFT:
case ABE_RIGHT:
hfont = (HFONT)SelectObject(hdc, s_hFontLeft);
x = rc.right - 2;
y = 2;
break;
}
// Draw the text and clean up
ExtTextOut(hdc, x, y, ETO_OPAQUE, NULL, L"Right Click for Options",
lstrlen(L"Right Click for Options"), NULL);
SelectObject(hdc, hfont);
EndPaint(hwnd, &ps);
}
//
// FUNCTION: Main_OnLButtonDown
//
// PURPOSE: This handler is called when the user is beginning to drag the
// appbar around the screen.
//
// PARAMETERS:
// hwnd - Handle of the appbar window being dragged.
// fDoubleClick - TRUE if this is a double click.
// x, y - Position of the mouse in client coordinates when then
// button was pressed.
// keyFlags - Keyboard state flags.
//
void Main_OnLButtonDown(HWND hwnd, BOOL /* fDoubleClick */, int /* x */, int /* y */, UINT /* keyFlags */)
{
s_fMoving = TRUE;
SetCapture(hwnd);
}
//
// FUNCTION: Main_OnMouseMove
//
// PURPOSE: We need to keep track of the mouse position, and update the
// appbar position when the mouse is in the appropriate quadrent
// of the screen.
//
// PARAMETERS:
// hwnd - Handle of the AppBar window.
// x, y - Position of the mouse in screen coordinates
// keyFlags - Keyboard state flags. Not used.
//
void Main_OnMouseMove(HWND hwnd, int x, int y, UINT /* keyFlags */)
{
// If we're not currently in the middle of moving the appbar window,
// there's nothing to do.
if (!s_fMoving)
{
return;
}
// Convert the mouse position to screen coordinates
POINT ptCursor = {x, y};
ClientToScreen(hwnd, &ptCursor);
// Find out which edge of the screen we're closest to
int cxScreen = GetSystemMetrics(SM_CXSCREEN);
int cyScreen = GetSystemMetrics(SM_CYSCREEN);
DWORD dx, dy;
WORD horiz, vert;
if (ptCursor.x < (cxScreen / 2))
{
dx = ptCursor.x;
horiz = ABE_LEFT;
}
else
{
dx = cxScreen - ptCursor.x;
horiz = ABE_RIGHT;
}
if (ptCursor.y < (cyScreen / 2))
{
dy = ptCursor.y;
vert = ABE_TOP;
}
else
{
dy = cyScreen - ptCursor.y;
vert = ABE_BOTTOM;
}
// Build a drag rectangle based on the edge of the screen that we're
// closest to.
POPTIONS pOpt = GetAppbarData(hwnd);
if ((cxScreen * dy) > (cyScreen * dx))
{
s_rcDrag.top = 0;
s_rcDrag.bottom = cyScreen;
if (horiz == ABE_LEFT)
{
s_rcDrag.left = 0;
s_rcDrag.right = s_rcDrag.left + pOpt->cxWidth;
pOpt->uSide = ABE_LEFT;
}
else
{
s_rcDrag.right = cxScreen;
s_rcDrag.left = s_rcDrag.right - pOpt->cxWidth;
pOpt->uSide = ABE_RIGHT;
}
}
else
{
s_rcDrag.left = 0;
s_rcDrag.right = cxScreen;
if (vert == ABE_TOP)
{
s_rcDrag.top = 0;
s_rcDrag.bottom = s_rcDrag.top + pOpt->cyHeight;
pOpt->uSide = ABE_TOP;
}
else
{
s_rcDrag.bottom = cyScreen;
s_rcDrag.top = s_rcDrag.bottom - pOpt->cyHeight;
pOpt->uSide = ABE_BOTTOM;
}
}
// Finally, make sure this is an OK position with the system and move
// the window.
APPBARDATA abd;
abd.cbSize = sizeof(APPBARDATA);
abd.hWnd = hwnd;
AppBar_QueryPos(hwnd, &s_rcDrag);
MoveWindow(hwnd, s_rcDrag.left, s_rcDrag.top,
s_rcDrag.right - s_rcDrag.left,
s_rcDrag.bottom - s_rcDrag.top,
TRUE);
}
//
// FUNCTION: Main_OnLButtonUp
//
// PURPOSE: The user is done dragging the window around, so we need to
// let the system know we have a new space to occupy.
//
// PARAMETERS:
// hwnd - Handle of the AppBar window.
// x, y - Position of the mouse in client coordinates.
// keyFlags - Keyboard state flags. Not used.
//
void Main_OnLButtonUp(HWND hwnd, int /* x */, int /* y */, UINT /* keyFlags */)
{
if (!s_fMoving)
{
return;
}
// Update the global appbar rect used when we're autohiding. This is
// sloppy but it works for now. It would be better to maintain two rects,
// one for the hidden state and one for the unhidden state.
g_rcAppBar = s_rcDrag;
// Clean up the drag state info.
ReleaseCapture();
// Calculate the hidden rect if we need to and then tell the system about
// our new area.
APPBARDATA abd;
abd.cbSize = sizeof(APPBARDATA);
abd.hWnd = hwnd;
POPTIONS pOpt = GetAppbarData(hwnd);
if (pOpt->fAutoHide)
{
switch (pOpt->uSide)
{
case ABE_TOP:
s_rcDrag.bottom = s_rcDrag.top + 2;
break;
case ABE_BOTTOM:
s_rcDrag.top = s_rcDrag.bottom - 2;
break;
case ABE_LEFT:
s_rcDrag.right = s_rcDrag.left + 2;
break;
case ABE_RIGHT:
s_rcDrag.left = s_rcDrag.right - 2;
break;
}
}
AppBar_QuerySetPos(pOpt->uSide, &s_rcDrag, &abd, FALSE);
s_fMoving = FALSE;
}
//
// FUNCTION: AboutDlgProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the About dialog box
//
// PARAMETERS:
// hwnd - window handle of the dialog box
// uMsg - identifier of the message being handled
// wParam - additional info associated with the message
// lParam - additional info associated with the message
//
// RETURN VALUE:
// Except in response to the WM_INITDIALOG message, the dialog box
// procedure should return nonzero if it processes the message, and zero
// if it does not.
//
INT_PTR CALLBACK AboutDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM /* lParam */)
{
switch(uMsg)
{
case WM_INITDIALOG:
// Should return nonzero to set focus to the first control in the
// dialog, or zero if this routine sets the focus manually.
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
EndDialog(hwnd, 0);
break;
}
return TRUE;
}
return FALSE;
}