632 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			632 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved.
 | |
|  *
 | |
|  *Permission is hereby granted, free of charge, to any person obtaining
 | |
|  * a copy of this software and associated documentation files (the
 | |
|  *"Software"), to deal in the Software without restriction, including
 | |
|  *without limitation the rights to use, copy, modify, merge, publish,
 | |
|  *distribute, sublicense, and/or sell copies of the Software, and to
 | |
|  *permit persons to whom the Software is furnished to do so, subject to
 | |
|  *the following conditions:
 | |
|  *
 | |
|  *The above copyright notice and this permission notice shall be
 | |
|  *included in all copies or substantial portions of the Software.
 | |
|  *
 | |
|  *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | |
|  *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | |
|  *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | |
|  *NONINFRINGEMENT. IN NO EVENT SHALL HAROLD L HUNT II BE LIABLE FOR
 | |
|  *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 | |
|  *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 | |
|  *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | |
|  *
 | |
|  *Except as contained in this notice, the name of Harold L Hunt II
 | |
|  *shall not be used in advertising or otherwise to promote the sale, use
 | |
|  *or other dealings in this Software without prior written authorization
 | |
|  *from Harold L Hunt II.
 | |
|  *
 | |
|  * Authors:	Harold L Hunt II
 | |
|  *              Earle F. Philhower III
 | |
|  */
 | |
| 
 | |
| #ifdef HAVE_XWIN_CONFIG_H
 | |
| #include <xwin-config.h>
 | |
| #endif
 | |
| #include "win.h"
 | |
| #include <shellapi.h>
 | |
| #include "winprefs.h"
 | |
| 
 | |
| /*
 | |
|  * Local function prototypes
 | |
|  */
 | |
| 
 | |
| static INT_PTR CALLBACK
 | |
| winExitDlgProc(HWND hDialog, UINT message, WPARAM wParam, LPARAM lParam);
 | |
| 
 | |
| static INT_PTR CALLBACK
 | |
| winChangeDepthDlgProc(HWND hDialog, UINT message, WPARAM wParam, LPARAM lParam);
 | |
| 
 | |
| static INT_PTR CALLBACK
 | |
| winAboutDlgProc(HWND hDialog, UINT message, WPARAM wParam, LPARAM lParam);
 | |
| 
 | |
| static void
 | |
|  winDrawURLWindow(LPARAM lParam);
 | |
| 
 | |
| static LRESULT CALLBACK
 | |
| winURLWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
 | |
| 
 | |
| static void
 | |
|  winOverrideURLButton(HWND hdlg, int id);
 | |
| 
 | |
| static void
 | |
|  winUnoverrideURLButton(HWND hdlg, int id);
 | |
| 
 | |
| /*
 | |
|  * Owner-draw a button as a URL
 | |
|  */
 | |
| 
 | |
| static void
 | |
| winDrawURLWindow(LPARAM lParam)
 | |
| {
 | |
|     DRAWITEMSTRUCT *draw;
 | |
|     char str[256];
 | |
|     RECT rect;
 | |
|     HFONT font;
 | |
|     COLORREF crText;
 | |
| 
 | |
|     draw = (DRAWITEMSTRUCT *) lParam;
 | |
|     GetWindowText(draw->hwndItem, str, sizeof(str));
 | |
|     str[255] = 0;
 | |
|     GetClientRect(draw->hwndItem, &rect);
 | |
| 
 | |
|     /* Color the button depending upon its state */
 | |
|     if (draw->itemState & ODS_SELECTED)
 | |
|         crText = RGB(128 + 64, 0, 0);
 | |
|     else if (draw->itemState & ODS_FOCUS)
 | |
|         crText = RGB(0, 128 + 64, 0);
 | |
|     else
 | |
|         crText = RGB(0, 0, 128 + 64);
 | |
|     SetTextColor(draw->hDC, crText);
 | |
| 
 | |
|     /* Create font 8 high, standard dialog font */
 | |
|     font = CreateFont(-8, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
 | |
|                       0, 0, 0, 0, 0, "MS Sans Serif");
 | |
|     if (!font) {
 | |
|         ErrorF("winDrawURLWindow: Unable to create URL font, bailing.\n");
 | |
|         return;
 | |
|     }
 | |
|     /* Draw it */
 | |
|     SetBkMode(draw->hDC, OPAQUE);
 | |
|     SelectObject(draw->hDC, font);
 | |
|     DrawText(draw->hDC, str, strlen(str), &rect, DT_LEFT | DT_VCENTER);
 | |
|     /* Delete the created font, replace it with stock font */
 | |
|     DeleteObject(SelectObject(draw->hDC, GetStockObject(ANSI_VAR_FONT)));
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * WndProc for overridden buttons
 | |
|  */
 | |
| 
 | |
| static LRESULT CALLBACK
 | |
| winURLWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 | |
| {
 | |
|     WNDPROC origCB = NULL;
 | |
|     HCURSOR cursor;
 | |
| 
 | |
|     /* If it's a SetCursor message, tell it to the hand */
 | |
|     if (msg == WM_SETCURSOR) {
 | |
|         cursor = LoadCursor(NULL, IDC_HAND);
 | |
|         if (cursor)
 | |
|             SetCursor(cursor);
 | |
|         return TRUE;
 | |
|     }
 | |
|     origCB = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_USERDATA);
 | |
|     /* Otherwise fall through to original WndProc */
 | |
|     if (origCB)
 | |
|         return CallWindowProc(origCB, hwnd, msg, wParam, lParam);
 | |
|     else
 | |
|         return FALSE;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Register and unregister the custom WndProc
 | |
|  */
 | |
| 
 | |
| static void
 | |
| winOverrideURLButton(HWND hwnd, int id)
 | |
| {
 | |
|     WNDPROC origCB;
 | |
| 
 | |
|     origCB = (WNDPROC) SetWindowLongPtr(GetDlgItem(hwnd, id),
 | |
|                                         GWLP_WNDPROC, (LONG_PTR) winURLWndProc);
 | |
|     SetWindowLongPtr(GetDlgItem(hwnd, id), GWLP_USERDATA, (LONG_PTR) origCB);
 | |
| }
 | |
| 
 | |
| static void
 | |
| winUnoverrideURLButton(HWND hwnd, int id)
 | |
| {
 | |
|     WNDPROC origCB;
 | |
| 
 | |
|     origCB = (WNDPROC) SetWindowLongPtr(GetDlgItem(hwnd, id), GWLP_USERDATA, 0);
 | |
|     if (origCB)
 | |
|         SetWindowLongPtr(GetDlgItem(hwnd, id), GWLP_WNDPROC, (LONG_PTR) origCB);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Center a dialog window in the desktop window
 | |
|  * and set small and large icons to X icons.
 | |
|  */
 | |
| 
 | |
| static void
 | |
| winInitDialog(HWND hwndDlg)
 | |
| {
 | |
|     HWND hwndDesk;
 | |
|     RECT rc, rcDlg, rcDesk;
 | |
|     HICON hIcon, hIconSmall;
 | |
| 
 | |
|     hwndDesk = GetParent(hwndDlg);
 | |
|     if (!hwndDesk || IsIconic(hwndDesk))
 | |
|         hwndDesk = GetDesktopWindow();
 | |
| 
 | |
|     /* Remove minimize and maximize buttons */
 | |
|     SetWindowLongPtr(hwndDlg, GWL_STYLE, GetWindowLongPtr(hwndDlg, GWL_STYLE)
 | |
|                      & ~(WS_MAXIMIZEBOX | WS_MINIMIZEBOX));
 | |
| 
 | |
|     /* Set Window not to show in the task bar */
 | |
|     SetWindowLongPtr(hwndDlg, GWL_EXSTYLE,
 | |
|                      GetWindowLongPtr(hwndDlg, GWL_EXSTYLE) & ~WS_EX_APPWINDOW);
 | |
| 
 | |
|     /* Center dialog window in the screen. Not done for multi-monitor systems, where
 | |
|      * it is likely to end up split across the screens. In that case, it appears
 | |
|      * near the Tray icon.
 | |
|      */
 | |
|     if (GetSystemMetrics(SM_CMONITORS) > 1) {
 | |
|         /* Still need to refresh the frame change. */
 | |
|         SetWindowPos(hwndDlg, HWND_TOPMOST, 0, 0, 0, 0,
 | |
|                      SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
 | |
|     }
 | |
|     else {
 | |
|         GetWindowRect(hwndDesk, &rcDesk);
 | |
|         GetWindowRect(hwndDlg, &rcDlg);
 | |
|         CopyRect(&rc, &rcDesk);
 | |
| 
 | |
|         OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
 | |
|         OffsetRect(&rc, -rc.left, -rc.top);
 | |
|         OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);
 | |
| 
 | |
|         SetWindowPos(hwndDlg,
 | |
|                      HWND_TOPMOST,
 | |
|                      rcDesk.left + (rc.right / 2),
 | |
|                      rcDesk.top + (rc.bottom / 2),
 | |
|                      0, 0, SWP_NOSIZE | SWP_FRAMECHANGED);
 | |
|     }
 | |
| 
 | |
|     if (g_hIconX)
 | |
|         hIcon = g_hIconX;
 | |
|     else
 | |
|         hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_XWIN));
 | |
| 
 | |
|     if (g_hSmallIconX)
 | |
|         hIconSmall = g_hSmallIconX;
 | |
|     else
 | |
|         hIconSmall = LoadImage(g_hInstance,
 | |
|                                MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON,
 | |
|                                GetSystemMetrics(SM_CXSMICON),
 | |
|                                GetSystemMetrics(SM_CYSMICON), LR_SHARED);
 | |
| 
 | |
|     PostMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
 | |
|     PostMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Display the Exit dialog box
 | |
|  */
 | |
| 
 | |
| void
 | |
| winDisplayExitDialog(winPrivScreenPtr pScreenPriv)
 | |
| {
 | |
|     int i;
 | |
|     int liveClients = 0;
 | |
| 
 | |
|     /* Count up running clients (clients[0] is serverClient) */
 | |
|     for (i = 1; i < currentMaxClients; i++)
 | |
|         if (clients[i] != NullClient)
 | |
|             liveClients++;
 | |
|     /* Count down server internal clients */
 | |
|     if (pScreenPriv->pScreenInfo->fMultiWindow)
 | |
|         liveClients -= 2;       /* multiwindow window manager & XMsgProc  */
 | |
|     if (g_fClipboardStarted)
 | |
|         liveClients--;          /* clipboard manager */
 | |
| 
 | |
|     /* A user reported that this sometimes drops below zero. just eye-candy. */
 | |
|     if (liveClients < 0)
 | |
|         liveClients = 0;
 | |
| 
 | |
|     /* Don't show the exit confirmation dialog if SilentExit & no clients,
 | |
|        or ForceExit, is enabled */
 | |
|     if ((pref.fSilentExit && liveClients <= 0) || pref.fForceExit) {
 | |
|         if (g_hDlgExit != NULL) {
 | |
|             DestroyWindow(g_hDlgExit);
 | |
|             g_hDlgExit = NULL;
 | |
|         }
 | |
|         PostMessage(pScreenPriv->hwndScreen, WM_GIVEUP, 0, 0);
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     pScreenPriv->iConnectedClients = liveClients;
 | |
| 
 | |
|     /* Check if dialog already exists */
 | |
|     if (g_hDlgExit != NULL) {
 | |
|         /* Dialog box already exists, display it */
 | |
|         ShowWindow(g_hDlgExit, SW_SHOWDEFAULT);
 | |
| 
 | |
|         /* User has lost the dialog.  Show them where it is. */
 | |
|         SetForegroundWindow(g_hDlgExit);
 | |
| 
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     /* Create dialog box */
 | |
|     g_hDlgExit = CreateDialogParam(g_hInstance,
 | |
|                                    "EXIT_DIALOG",
 | |
|                                    pScreenPriv->hwndScreen,
 | |
|                                    winExitDlgProc, (LPARAM) pScreenPriv);
 | |
| 
 | |
|     /* Show the dialog box */
 | |
|     ShowWindow(g_hDlgExit, SW_SHOW);
 | |
| 
 | |
|     /* Needed to get keyboard controls (tab, arrows, enter, esc) to work */
 | |
|     SetForegroundWindow(g_hDlgExit);
 | |
| 
 | |
|     /* Set focus to the Cancel button */
 | |
|     PostMessage(g_hDlgExit, WM_NEXTDLGCTL,
 | |
|                 (WPARAM) GetDlgItem(g_hDlgExit, IDCANCEL), TRUE);
 | |
| }
 | |
| 
 | |
| #define CONNECTED_CLIENTS_FORMAT	"There %s currently %d client%s connected."
 | |
| 
 | |
| /*
 | |
|  * Exit dialog window procedure
 | |
|  */
 | |
| 
 | |
| static INT_PTR CALLBACK
 | |
| winExitDlgProc(HWND hDialog, UINT message, WPARAM wParam, LPARAM lParam)
 | |
| {
 | |
|     static winPrivScreenPtr s_pScreenPriv = NULL;
 | |
| 
 | |
|     /* Branch on message type */
 | |
|     switch (message) {
 | |
|     case WM_INITDIALOG:
 | |
|     {
 | |
|         char *pszConnectedClients;
 | |
| 
 | |
|         /* Store pointers to private structures for future use */
 | |
|         s_pScreenPriv = (winPrivScreenPtr) lParam;
 | |
| 
 | |
|         winInitDialog(hDialog);
 | |
| 
 | |
|         /* Format the connected clients string */
 | |
|         if (asprintf(&pszConnectedClients, CONNECTED_CLIENTS_FORMAT,
 | |
|                      (s_pScreenPriv->iConnectedClients == 1) ? "is" : "are",
 | |
|                      s_pScreenPriv->iConnectedClients,
 | |
|                      (s_pScreenPriv->iConnectedClients == 1) ? "" : "s") == -1)
 | |
|             return TRUE;
 | |
| 
 | |
|         /* Set the number of connected clients */
 | |
|         SetWindowText(GetDlgItem(hDialog, IDC_CLIENTS_CONNECTED),
 | |
|                       pszConnectedClients);
 | |
|         free(pszConnectedClients);
 | |
|     }
 | |
|         return TRUE;
 | |
| 
 | |
|     case WM_COMMAND:
 | |
|         switch (LOWORD(wParam)) {
 | |
|         case IDOK:
 | |
|             /* Send message to call the GiveUp function */
 | |
|             PostMessage(s_pScreenPriv->hwndScreen, WM_GIVEUP, 0, 0);
 | |
|             DestroyWindow(g_hDlgExit);
 | |
|             g_hDlgExit = NULL;
 | |
| 
 | |
|             /* Fix to make sure keyboard focus isn't trapped */
 | |
|             PostMessage(s_pScreenPriv->hwndScreen, WM_NULL, 0, 0);
 | |
|             return TRUE;
 | |
| 
 | |
|         case IDCANCEL:
 | |
|             DestroyWindow(g_hDlgExit);
 | |
|             g_hDlgExit = NULL;
 | |
| 
 | |
|             /* Fix to make sure keyboard focus isn't trapped */
 | |
|             PostMessage(s_pScreenPriv->hwndScreen, WM_NULL, 0, 0);
 | |
|             return TRUE;
 | |
|         }
 | |
|         break;
 | |
| 
 | |
|     case WM_MOUSEMOVE:
 | |
|     case WM_NCMOUSEMOVE:
 | |
|         /* Show the cursor if it is hidden */
 | |
|         if (g_fSoftwareCursor && !g_fCursor) {
 | |
|             g_fCursor = TRUE;
 | |
|             ShowCursor(TRUE);
 | |
|         }
 | |
|         return TRUE;
 | |
| 
 | |
|     case WM_CLOSE:
 | |
|         DestroyWindow(g_hDlgExit);
 | |
|         g_hDlgExit = NULL;
 | |
| 
 | |
|         /* Fix to make sure keyboard focus isn't trapped */
 | |
|         PostMessage(s_pScreenPriv->hwndScreen, WM_NULL, 0, 0);
 | |
|         return TRUE;
 | |
|     }
 | |
| 
 | |
|     return FALSE;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Display the Depth Change dialog box
 | |
|  */
 | |
| 
 | |
| void
 | |
| winDisplayDepthChangeDialog(winPrivScreenPtr pScreenPriv)
 | |
| {
 | |
|     /* Check if dialog already exists */
 | |
|     if (g_hDlgDepthChange != NULL) {
 | |
|         /* Dialog box already exists, display it */
 | |
|         ShowWindow(g_hDlgDepthChange, SW_SHOWDEFAULT);
 | |
| 
 | |
|         /* User has lost the dialog.  Show them where it is. */
 | |
|         SetForegroundWindow(g_hDlgDepthChange);
 | |
| 
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * Display a notification to the user that the visual
 | |
|      * will not be displayed until the Windows display depth
 | |
|      * is restored to the original value.
 | |
|      */
 | |
|     g_hDlgDepthChange = CreateDialogParam(g_hInstance,
 | |
|                                           "DEPTH_CHANGE_BOX",
 | |
|                                           pScreenPriv->hwndScreen,
 | |
|                                           winChangeDepthDlgProc,
 | |
|                                           (LPARAM) pScreenPriv);
 | |
|     /* Show the dialog box */
 | |
|     ShowWindow(g_hDlgDepthChange, SW_SHOW);
 | |
| 
 | |
|     if (!g_hDlgDepthChange)
 | |
|         ErrorF("winDisplayDepthChangeDialog - GetLastError: %d\n",
 | |
|                 (int) GetLastError());
 | |
| 
 | |
|     /* Minimize the display window */
 | |
|     ShowWindow(pScreenPriv->hwndScreen, SW_MINIMIZE);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Process messages for the dialog that is displayed for
 | |
|  * disruptive screen depth changes.
 | |
|  */
 | |
| 
 | |
| static INT_PTR CALLBACK
 | |
| winChangeDepthDlgProc(HWND hwndDialog, UINT message,
 | |
|                       WPARAM wParam, LPARAM lParam)
 | |
| {
 | |
|     static winPrivScreenPtr s_pScreenPriv = NULL;
 | |
|     static winScreenInfo *s_pScreenInfo = NULL;
 | |
| 
 | |
| #if ENABLE_DEBUG
 | |
|     winDebug("winChangeDepthDlgProc\n");
 | |
| #endif
 | |
| 
 | |
|     /* Branch on message type */
 | |
|     switch (message) {
 | |
|     case WM_INITDIALOG:
 | |
| #if ENABLE_DEBUG
 | |
|         winDebug("winChangeDepthDlgProc - WM_INITDIALOG\n");
 | |
| #endif
 | |
| 
 | |
|         /* Store pointers to private structures for future use */
 | |
|         s_pScreenPriv = (winPrivScreenPtr) lParam;
 | |
|         s_pScreenInfo = s_pScreenPriv->pScreenInfo;
 | |
| 
 | |
| #if ENABLE_DEBUG
 | |
|         winDebug("winChangeDepthDlgProc - WM_INITDIALOG - s_pScreenPriv: %p, "
 | |
|                  "s_pScreenInfo: %p\n",
 | |
|                  s_pScreenPriv, s_pScreenInfo);
 | |
| #endif
 | |
| 
 | |
| #if ENABLE_DEBUG
 | |
|         winDebug("winChangeDepthDlgProc - WM_INITDIALOG - orig bpp: %u, "
 | |
|                  "current bpp: %d\n",
 | |
|                  (unsigned int)s_pScreenInfo->dwBPP,
 | |
|                  GetDeviceCaps(s_pScreenPriv->hdcScreen, BITSPIXEL));
 | |
| #endif
 | |
| 
 | |
|         winInitDialog(hwndDialog);
 | |
| 
 | |
|         return TRUE;
 | |
| 
 | |
|     case WM_DISPLAYCHANGE:
 | |
| #if ENABLE_DEBUG
 | |
|         winDebug("winChangeDepthDlgProc - WM_DISPLAYCHANGE - orig bpp: %u, "
 | |
|                  "new bpp: %d\n",
 | |
|                  (unsigned int)s_pScreenInfo->dwBPP,
 | |
|                  GetDeviceCaps(s_pScreenPriv->hdcScreen, BITSPIXEL));
 | |
| #endif
 | |
| 
 | |
|         /* Dismiss the dialog if the display returns to the original depth */
 | |
|         if (GetDeviceCaps(s_pScreenPriv->hdcScreen, BITSPIXEL) ==
 | |
|             s_pScreenInfo->dwBPP) {
 | |
|             ErrorF("winChangeDelthDlgProc - wParam == s_pScreenInfo->dwBPP\n");
 | |
| 
 | |
|             /* Depth has been restored, dismiss dialog */
 | |
|             DestroyWindow(g_hDlgDepthChange);
 | |
|             g_hDlgDepthChange = NULL;
 | |
| 
 | |
|             /* Flag that we have a valid screen depth */
 | |
|             s_pScreenPriv->fBadDepth = FALSE;
 | |
|         }
 | |
|         return TRUE;
 | |
| 
 | |
|     case WM_COMMAND:
 | |
|         switch (LOWORD(wParam)) {
 | |
|         case IDOK:
 | |
|         case IDCANCEL:
 | |
|             winDebug("winChangeDepthDlgProc - WM_COMMAND - IDOK or IDCANCEL\n");
 | |
| 
 | |
|             /*
 | |
|              * User dismissed the dialog, hide it until the
 | |
|              * display mode is restored.
 | |
|              */
 | |
|             ShowWindow(g_hDlgDepthChange, SW_HIDE);
 | |
|             return TRUE;
 | |
|         }
 | |
|         break;
 | |
| 
 | |
|     case WM_CLOSE:
 | |
|         winDebug("winChangeDepthDlgProc - WM_CLOSE\n");
 | |
| 
 | |
|         DestroyWindow(g_hDlgAbout);
 | |
|         g_hDlgAbout = NULL;
 | |
| 
 | |
|         /* Fix to make sure keyboard focus isn't trapped */
 | |
|         PostMessage(s_pScreenPriv->hwndScreen, WM_NULL, 0, 0);
 | |
|         return TRUE;
 | |
|     }
 | |
| 
 | |
|     return FALSE;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Display the About dialog box
 | |
|  */
 | |
| 
 | |
| void
 | |
| winDisplayAboutDialog(winPrivScreenPtr pScreenPriv)
 | |
| {
 | |
|     /* Check if dialog already exists */
 | |
|     if (g_hDlgAbout != NULL) {
 | |
|         /* Dialog box already exists, display it */
 | |
|         ShowWindow(g_hDlgAbout, SW_SHOWDEFAULT);
 | |
| 
 | |
|         /* User has lost the dialog.  Show them where it is. */
 | |
|         SetForegroundWindow(g_hDlgAbout);
 | |
| 
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     /*
 | |
|      * Display the about box
 | |
|      */
 | |
|     g_hDlgAbout = CreateDialogParam(g_hInstance,
 | |
|                                     "ABOUT_BOX",
 | |
|                                     pScreenPriv->hwndScreen,
 | |
|                                     winAboutDlgProc, (LPARAM) pScreenPriv);
 | |
| 
 | |
|     /* Show the dialog box */
 | |
|     ShowWindow(g_hDlgAbout, SW_SHOW);
 | |
| 
 | |
|     /* Needed to get keyboard controls (tab, arrows, enter, esc) to work */
 | |
|     SetForegroundWindow(g_hDlgAbout);
 | |
| 
 | |
|     /* Set focus to the OK button */
 | |
|     PostMessage(g_hDlgAbout, WM_NEXTDLGCTL,
 | |
|                 (WPARAM) GetDlgItem(g_hDlgAbout, IDOK), TRUE);
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Process messages for the about dialog.
 | |
|  */
 | |
| 
 | |
| static INT_PTR CALLBACK
 | |
| winAboutDlgProc(HWND hwndDialog, UINT message, WPARAM wParam, LPARAM lParam)
 | |
| {
 | |
|     static winPrivScreenPtr s_pScreenPriv = NULL;
 | |
| 
 | |
| #if ENABLE_DEBUG
 | |
|     winDebug("winAboutDlgProc\n");
 | |
| #endif
 | |
| 
 | |
|     /* Branch on message type */
 | |
|     switch (message) {
 | |
|     case WM_INITDIALOG:
 | |
| #if ENABLE_DEBUG
 | |
|         winDebug("winAboutDlgProc - WM_INITDIALOG\n");
 | |
| #endif
 | |
| 
 | |
|         /* Store pointer to private structure for future use */
 | |
|         s_pScreenPriv = (winPrivScreenPtr) lParam;
 | |
| 
 | |
|         winInitDialog(hwndDialog);
 | |
| 
 | |
|         /* Override the URL buttons */
 | |
|         winOverrideURLButton(hwndDialog, ID_ABOUT_WEBSITE);
 | |
| 
 | |
|         return TRUE;
 | |
| 
 | |
|     case WM_DRAWITEM:
 | |
|         /* Draw the URL buttons as needed */
 | |
|         winDrawURLWindow(lParam);
 | |
|         return TRUE;
 | |
| 
 | |
|     case WM_MOUSEMOVE:
 | |
|     case WM_NCMOUSEMOVE:
 | |
|         /* Show the cursor if it is hidden */
 | |
|         if (g_fSoftwareCursor && !g_fCursor) {
 | |
|             g_fCursor = TRUE;
 | |
|             ShowCursor(TRUE);
 | |
|         }
 | |
|         return TRUE;
 | |
| 
 | |
|     case WM_COMMAND:
 | |
|         switch (LOWORD(wParam)) {
 | |
|         case IDOK:
 | |
|         case IDCANCEL:
 | |
|             winDebug("winAboutDlgProc - WM_COMMAND - IDOK or IDCANCEL\n");
 | |
| 
 | |
|             DestroyWindow(g_hDlgAbout);
 | |
|             g_hDlgAbout = NULL;
 | |
| 
 | |
|             /* Fix to make sure keyboard focus isn't trapped */
 | |
|             PostMessage(s_pScreenPriv->hwndScreen, WM_NULL, 0, 0);
 | |
| 
 | |
|             /* Restore window procedures for URL buttons */
 | |
|             winUnoverrideURLButton(hwndDialog, ID_ABOUT_WEBSITE);
 | |
| 
 | |
|             return TRUE;
 | |
| 
 | |
|         case ID_ABOUT_WEBSITE:
 | |
|         {
 | |
|             const char *pszPath = __VENDORDWEBSUPPORT__;
 | |
|             INT_PTR iReturn;
 | |
| 
 | |
|             iReturn = (INT_PTR) ShellExecute(NULL,
 | |
|                                          "open",
 | |
|                                          pszPath, NULL, NULL, SW_MAXIMIZE);
 | |
|             if (iReturn < 32) {
 | |
|                 ErrorF("winAboutDlgProc - WM_COMMAND - ID_ABOUT_WEBSITE - "
 | |
|                        "ShellExecute failed: %d\n", (int)iReturn);
 | |
| 
 | |
|             }
 | |
|         }
 | |
|             return TRUE;
 | |
|         }
 | |
|         break;
 | |
| 
 | |
|     case WM_CLOSE:
 | |
|         winDebug("winAboutDlgProc - WM_CLOSE\n");
 | |
| 
 | |
|         DestroyWindow(g_hDlgAbout);
 | |
|         g_hDlgAbout = NULL;
 | |
| 
 | |
|         /* Fix to make sure keyboard focus isn't trapped */
 | |
|         PostMessage(s_pScreenPriv->hwndScreen, WM_NULL, 0, 0);
 | |
| 
 | |
|         /* Restore window procedures for URL buttons */
 | |
|         winUnoverrideURLButton(hwndDialog, ID_ABOUT_WEBSITE);
 | |
| 
 | |
|         return TRUE;
 | |
|     }
 | |
| 
 | |
|     return FALSE;
 | |
| }
 |