You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
810 lines
19 KiB
810 lines
19 KiB
/////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 1998 Active Voice Corporation. All Rights Reserved.
|
|
//
|
|
// Active Agent(r) and Unified Communications(tm) are trademarks of Active Voice Corporation.
|
|
//
|
|
// Other brand and product names used herein are trademarks of their respective owners.
|
|
//
|
|
// The entire program and user interface including the structure, sequence, selection,
|
|
// and arrangement of the dialog, the exclusively "yes" and "no" choices represented
|
|
// by "1" and "2," and each dialog message are protected by copyrights registered in
|
|
// the United States and by international treaties.
|
|
//
|
|
// Protected by one or more of the following United States patents: 5,070,526, 5,488,650,
|
|
// 5,434,906, 5,581,604, 5,533,102, 5,568,540, 5,625,676, 5,651,054.
|
|
//
|
|
// Active Voice Corporation
|
|
// Seattle, Washington
|
|
// USA
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
////
|
|
// nbox.c - notify box functions
|
|
////
|
|
|
|
#include "winlocal.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "nbox.h"
|
|
#include "escbutt.h"
|
|
#include "gfx.h"
|
|
#include "mem.h"
|
|
#include "str.h"
|
|
#include "trace.h"
|
|
#include "wnd.h"
|
|
|
|
////
|
|
// private definitions
|
|
////
|
|
|
|
#define NBOXCLASS TEXT("NBoxClass")
|
|
#define NBOXMAXCOLUMNS 60
|
|
#define NBOXMAXROWS 20
|
|
|
|
// nbox control struct
|
|
//
|
|
typedef struct NBOX
|
|
{
|
|
DWORD dwVersion;
|
|
HINSTANCE hInst;
|
|
HTASK hTask;
|
|
LPTSTR lpszText;
|
|
DWORD dwFlags;
|
|
HWND hwndNBox;
|
|
BOOL fVisible;
|
|
HWND hwndCancel;
|
|
BOOL fCancelled;
|
|
HWND hwndFocusOld;
|
|
HCURSOR hCursorOld;
|
|
} NBOX, FAR *LPNBOX;
|
|
|
|
// helper functions
|
|
//
|
|
LRESULT DLLEXPORT CALLBACK NBoxWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
static BOOL NBoxOnNCCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct);
|
|
static void NBoxOnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify);
|
|
static void NBoxOnPaint(HWND hwnd);
|
|
static LPNBOX NBoxGetPtr(HNBOX hNBox);
|
|
static HNBOX NBoxGetHandle(LPNBOX lpNBox);
|
|
|
|
////
|
|
// public functions
|
|
////
|
|
|
|
// NBoxCreate - notify box constructor
|
|
// <dwVersion> (i) must be NBOX_VERSION
|
|
// <hInst> (i) instance handle of calling module
|
|
// <hwndParent> (i) window which will own the notify box
|
|
// NULL desktop window
|
|
// <lpszText> (i) message to be displayed
|
|
// <lpszTitle> (i) notify box caption
|
|
// NULL no caption
|
|
// <lpszButtonText> (i) pushbutton text, if NB_CANCEL specified
|
|
// NULL use default text ("Cancel")
|
|
// <dwFlags> (i) control flags
|
|
// NB_CANCEL notify box includes Cancel pushbutton
|
|
// NB_TASKMODAL disable parent task's top-level windows
|
|
// NB_HOURGLASS show hourglass cursor while notify box visible
|
|
// return notify box handle (NULL if error)
|
|
//
|
|
// NOTE: NBoxCreate creates the window but does not show it.
|
|
// See NBoxShow and NBoxHide.
|
|
// The size of the notify box is determined by the number of
|
|
// lines in <lpszText>, and the length of the longest line.
|
|
//
|
|
HNBOX DLLEXPORT WINAPI NBoxCreate(DWORD dwVersion, HINSTANCE hInst,
|
|
HWND hwndParent, LPCTSTR lpszText, LPCTSTR lpszTitle,
|
|
LPCTSTR lpszButtonText, DWORD dwFlags)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPNBOX lpNBox = NULL;
|
|
WNDCLASS wc;
|
|
int nRows;
|
|
int nColumns;
|
|
int cxChar;
|
|
int cyChar;
|
|
|
|
if (dwVersion != NBOX_VERSION)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else if (hInst == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else if (lpszText == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else if ((lpNBox = (LPNBOX) MemAlloc(NULL, sizeof(NBOX), 0)) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else
|
|
{
|
|
lpNBox->dwVersion = dwVersion;
|
|
lpNBox->hInst = hInst;
|
|
lpNBox->hTask = GetCurrentTask();
|
|
lpNBox->lpszText = NULL;
|
|
lpNBox->dwFlags = dwFlags;
|
|
lpNBox->hwndNBox = NULL;
|
|
lpNBox->fVisible = FALSE;
|
|
lpNBox->hwndCancel = NULL;
|
|
lpNBox->fCancelled = FALSE;
|
|
lpNBox->hwndFocusOld = NULL;
|
|
lpNBox->hCursorOld = NULL;
|
|
|
|
if (hwndParent == NULL)
|
|
hwndParent = GetDesktopWindow();
|
|
|
|
if ((lpNBox->lpszText = StrDup(lpszText)) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
}
|
|
|
|
// register notify box class unless it has been already
|
|
//
|
|
if (fSuccess && GetClassInfo(lpNBox->hInst, NBOXCLASS, &wc) == 0)
|
|
{
|
|
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
|
wc.hIcon = (HICON) NULL;
|
|
wc.lpszMenuName = NULL;
|
|
wc.hInstance = lpNBox->hInst;
|
|
wc.lpszClassName = NBOXCLASS;
|
|
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
|
|
wc.lpfnWndProc = NBoxWndProc;
|
|
wc.style = 0L;
|
|
wc.cbWndExtra = sizeof(lpNBox);
|
|
wc.cbClsExtra = 0;
|
|
|
|
if (!RegisterClass(&wc))
|
|
fSuccess = TraceFALSE(NULL);
|
|
}
|
|
|
|
// create a notify box window
|
|
//
|
|
if (fSuccess && (lpNBox->hwndNBox = CreateWindowEx(
|
|
WS_EX_DLGMODALFRAME,
|
|
NBOXCLASS,
|
|
(LPTSTR) lpszTitle,
|
|
WS_POPUP | (lpszTitle == NULL ? 0 : WS_CAPTION), // | WS_DLGFRAME,
|
|
0, 0, 0, 0, // we will calculate size and position later
|
|
#if 1
|
|
hwndParent,
|
|
#else
|
|
(HWND) NULL,
|
|
#endif
|
|
(HMENU) NULL,
|
|
lpNBox->hInst,
|
|
lpNBox)) == NULL)
|
|
{
|
|
fSuccess = TraceFALSE(NULL);
|
|
}
|
|
|
|
// calculate avg char width and height
|
|
//
|
|
if (fSuccess)
|
|
{
|
|
HDC hdc = NULL;
|
|
TEXTMETRIC tm;
|
|
|
|
if ((hdc = GetDC(hwndParent)) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else if (!GetTextMetrics(hdc, &tm))
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else
|
|
{
|
|
cxChar = tm.tmAveCharWidth;
|
|
cyChar = tm.tmHeight + tm.tmExternalLeading;
|
|
}
|
|
|
|
if (hdc != NULL && !ReleaseDC(hwndParent, hdc))
|
|
fSuccess = TraceFALSE(NULL);
|
|
}
|
|
|
|
if (fSuccess)
|
|
{
|
|
// calculate size of text
|
|
//
|
|
if (StrGetRowColumnCount(lpszText, &nRows, &nColumns) != 0)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
nRows = min(nRows, NBOXMAXROWS);
|
|
nColumns = min(nColumns, NBOXMAXCOLUMNS);
|
|
}
|
|
|
|
if (fSuccess)
|
|
{
|
|
int cxNBox;
|
|
int cyNBox;
|
|
int cxCancel;
|
|
int cyCancel;
|
|
int xCancel;
|
|
int yCancel;
|
|
|
|
// calculate window size
|
|
//
|
|
cxNBox = (nColumns + 10) * cxChar +
|
|
2 * GetSystemMetrics(SM_CXBORDER);
|
|
cyNBox = (nRows + 4) * cyChar +
|
|
2 * GetSystemMetrics(SM_CYBORDER);
|
|
|
|
// increase notify box size to accomodate caption
|
|
//
|
|
if (lpszTitle != NULL)
|
|
cyNBox += GetSystemMetrics(SM_CYCAPTION);
|
|
|
|
|
|
if (lpNBox->dwFlags & NB_CANCEL)
|
|
{
|
|
// calculate cancel button size
|
|
//
|
|
cxCancel = (40 * (int) LOWORD(GetDialogBaseUnits())) / 4;
|
|
cyCancel = (14 * (int) HIWORD(GetDialogBaseUnits())) / 8;
|
|
|
|
// increase notify box size to accomodate CANCEL button
|
|
//
|
|
cxNBox = max(cxNBox, cxCancel);
|
|
cyNBox += cyCancel * 2;
|
|
|
|
// calculate cancel button position
|
|
//
|
|
xCancel = (cxNBox - cxCancel) / 2;
|
|
yCancel = (cyNBox - (cyCancel * 2));
|
|
|
|
// modify cancel button position to accomodate caption
|
|
//
|
|
if (lpszTitle != NULL)
|
|
yCancel -= GetSystemMetrics(SM_CYCAPTION);
|
|
}
|
|
|
|
// set window size
|
|
//
|
|
if (!SetWindowPos(lpNBox->hwndNBox,
|
|
NULL, 0, 0, cxNBox, cyNBox,
|
|
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOZORDER))
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
// center the window on its parent
|
|
//
|
|
else if (WndCenterWindow(lpNBox->hwndNBox, hwndParent, 0, 0) != 0)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else if ((lpNBox->dwFlags & NB_CANCEL))
|
|
{
|
|
// create cancel button as child of notify box
|
|
//
|
|
if ((lpNBox->hwndCancel = CreateWindowEx(
|
|
0L,
|
|
TEXT("BUTTON"),
|
|
lpszButtonText == NULL ? TEXT("Cancel") : lpszButtonText,
|
|
WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
|
|
xCancel, yCancel, cxCancel, cyCancel,
|
|
(HWND) lpNBox->hwndNBox,
|
|
(HMENU) IDCANCEL,
|
|
lpNBox->hInst,
|
|
NULL)) == NULL)
|
|
{
|
|
fSuccess = TraceFALSE(NULL);
|
|
}
|
|
|
|
// subclass the cancel button, so the escape key pushes it
|
|
//
|
|
else if (EscButtInit(lpNBox->hwndCancel, 0) != 0)
|
|
fSuccess = TraceFALSE(NULL);
|
|
}
|
|
}
|
|
|
|
if (!fSuccess)
|
|
{
|
|
NBoxDestroy(NBoxGetHandle(lpNBox));
|
|
lpNBox = NULL;
|
|
}
|
|
|
|
return fSuccess ? NBoxGetHandle(lpNBox) : NULL;
|
|
}
|
|
|
|
// NBoxDestroy - notify box destructor
|
|
// <hNBox> (i) handle returned from NBoxCreate
|
|
// return 0 if success
|
|
//
|
|
int DLLEXPORT WINAPI NBoxDestroy(HNBOX hNBox)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPNBOX lpNBox;
|
|
|
|
if (NBoxHide(hNBox) != 0)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else if ((lpNBox = NBoxGetPtr(hNBox)) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else
|
|
{
|
|
// destroy text string
|
|
//
|
|
if (lpNBox->lpszText != NULL &&
|
|
StrDupFree(lpNBox->lpszText) != 0)
|
|
fSuccess = TraceFALSE(NULL);
|
|
else
|
|
lpNBox->lpszText = NULL;
|
|
|
|
// destroy cancel button
|
|
//
|
|
if (lpNBox->hwndCancel != NULL)
|
|
{
|
|
if (EscButtTerm(lpNBox->hwndCancel) != 0)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
if (!DestroyWindow(lpNBox->hwndCancel))
|
|
fSuccess = TraceFALSE(NULL);
|
|
else
|
|
lpNBox->hwndCancel = NULL;
|
|
}
|
|
|
|
// destroy notify box
|
|
//
|
|
if (lpNBox->hwndNBox != NULL &&
|
|
!DestroyWindow(lpNBox->hwndNBox))
|
|
fSuccess = TraceFALSE(NULL);
|
|
else
|
|
lpNBox->hwndNBox = NULL;
|
|
|
|
// destroy control struct
|
|
//
|
|
if ((lpNBox = MemFree(NULL, lpNBox)) != NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
}
|
|
|
|
return fSuccess ? 0 : -1;
|
|
}
|
|
|
|
// NBoxShow - show notify box
|
|
// <hNBox> (i) handle returned from NBoxCreate
|
|
// return 0 if success
|
|
//
|
|
int DLLEXPORT WINAPI NBoxShow(HNBOX hNBox)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPNBOX lpNBox;
|
|
|
|
if ((lpNBox = NBoxGetPtr(hNBox)) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else if (lpNBox->fVisible)
|
|
; // already visible, so no need to do anything else
|
|
|
|
else
|
|
{
|
|
HWND hwndParent = GetParent(lpNBox->hwndNBox);
|
|
|
|
// disable other windows in this task if necessary
|
|
//
|
|
if (lpNBox->dwFlags & NB_TASKMODAL)
|
|
{
|
|
HTASK hTaskParent;
|
|
|
|
if (hwndParent != NULL)
|
|
hTaskParent = GetWindowTask(hwndParent);
|
|
else
|
|
hTaskParent = lpNBox->hTask;
|
|
|
|
if (WndEnableTaskWindows(hTaskParent, FALSE, lpNBox->hwndNBox) != 0)
|
|
TraceFALSE(NULL); // not a fatal error
|
|
}
|
|
|
|
// otherwise just disable parent of notify box
|
|
//
|
|
else if (hwndParent != NULL)
|
|
EnableWindow(hwndParent, FALSE);
|
|
|
|
if (fSuccess)
|
|
{
|
|
// show the window
|
|
//
|
|
ShowWindow(lpNBox->hwndNBox, TRUE ? SW_SHOW : SW_SHOWNA);
|
|
UpdateWindow(lpNBox->hwndNBox);
|
|
lpNBox->fVisible = TRUE;
|
|
|
|
// set focus to cancel button if necessary
|
|
//
|
|
if (lpNBox->dwFlags & NB_CANCEL && lpNBox->hwndCancel != NULL)
|
|
lpNBox->hwndFocusOld = SetFocus(lpNBox->hwndCancel);
|
|
}
|
|
|
|
// display hourglass cursor if specified
|
|
//
|
|
if (fSuccess && lpNBox->dwFlags & NB_HOURGLASS)
|
|
lpNBox->hCursorOld = GfxShowHourglass(lpNBox->hwndNBox);
|
|
}
|
|
|
|
return fSuccess ? 0 : -1;
|
|
}
|
|
|
|
// NBoxHide - hide notify box
|
|
// <hNBox> (i) handle returned from NBoxCreate
|
|
// return 0 if success
|
|
//
|
|
int DLLEXPORT WINAPI NBoxHide(HNBOX hNBox)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPNBOX lpNBox;
|
|
|
|
if ((lpNBox = NBoxGetPtr(hNBox)) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else if (!lpNBox->fVisible)
|
|
; // already hidden, so no need to do anything else
|
|
|
|
else
|
|
{
|
|
HWND hwndParent = GetParent(lpNBox->hwndNBox);
|
|
|
|
// enable other windows in this task if necessary
|
|
//
|
|
if (lpNBox->dwFlags & NB_TASKMODAL)
|
|
{
|
|
HTASK hTaskParent;
|
|
|
|
if (hwndParent != NULL)
|
|
hTaskParent = GetWindowTask(hwndParent);
|
|
else
|
|
hTaskParent = lpNBox->hTask;
|
|
|
|
if (WndEnableTaskWindows(hTaskParent, TRUE, NULL) != 0)
|
|
TraceFALSE(NULL); // not a fatal error
|
|
}
|
|
|
|
// otherwise just enable parent of notify box
|
|
//
|
|
else if (hwndParent != NULL)
|
|
EnableWindow(hwndParent, TRUE);
|
|
|
|
if (fSuccess)
|
|
{
|
|
// hide the window
|
|
//
|
|
ShowWindow(lpNBox->hwndNBox, SW_HIDE);
|
|
UpdateWindow(lpNBox->hwndNBox);
|
|
lpNBox->fVisible = FALSE;
|
|
|
|
// remove focus from cancel button if necessary
|
|
//
|
|
if (lpNBox->dwFlags & NB_CANCEL &&
|
|
lpNBox->hwndCancel != NULL &&
|
|
GetFocus() == lpNBox->hwndCancel)
|
|
SetFocus(lpNBox->hwndFocusOld);
|
|
}
|
|
|
|
// hide hourglass, restore old cursor
|
|
//
|
|
if (fSuccess && lpNBox->dwFlags & NB_HOURGLASS)
|
|
{
|
|
if (GfxHideHourglass(lpNBox->hCursorOld) != 0)
|
|
fSuccess = TraceFALSE(NULL);
|
|
else
|
|
lpNBox->hCursorOld = NULL;
|
|
}
|
|
}
|
|
|
|
return fSuccess ? 0 : -1;
|
|
}
|
|
|
|
// NBoxIsVisible - get visible flag
|
|
// <hNBox> (i) handle returned from NBoxCreate
|
|
// return TRUE if notify box is visible, FALSE if hidden
|
|
//
|
|
int DLLEXPORT WINAPI NBoxIsVisible(HNBOX hNBox)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPNBOX lpNBox;
|
|
|
|
if ((lpNBox = NBoxGetPtr(hNBox)) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
return fSuccess ? lpNBox->fVisible : FALSE;
|
|
}
|
|
|
|
// NBoxGetWindowHandle - get notify box window handle
|
|
// <hNBox> (i) handle returned from NBoxCreate
|
|
// return window handle (NULL if error)
|
|
//
|
|
HWND DLLEXPORT WINAPI NBoxGetWindowHandle(HNBOX hNBox)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPNBOX lpNBox;
|
|
|
|
if ((lpNBox = NBoxGetPtr(hNBox)) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
return fSuccess ? lpNBox->hwndNBox : NULL;
|
|
}
|
|
|
|
// NBoxSetText - set notify box message text
|
|
// <hNBox> (i) handle returned from NBoxCreate
|
|
// <lpszText> (i) message to be displayed
|
|
// NULL do not modify text
|
|
// <lpszTitle> (i) notify box caption
|
|
// NULL do not modify caption
|
|
// return 0 if success
|
|
//
|
|
// NOTE: The size of the notify box is not changed by this function,
|
|
// even if <lpszText> is larger than when NBoxCreate() was called.
|
|
//
|
|
int DLLEXPORT WINAPI NBoxSetText(HNBOX hNBox, LPCTSTR lpszText, LPCTSTR lpszTitle)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPNBOX lpNBox;
|
|
|
|
if ((lpNBox = NBoxGetPtr(hNBox)) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else
|
|
{
|
|
if (lpszTitle != NULL)
|
|
{
|
|
// set new title
|
|
//
|
|
SetWindowText(lpNBox->hwndNBox, lpszTitle);
|
|
}
|
|
|
|
if (lpszText != NULL)
|
|
{
|
|
// dispose of previous text
|
|
//
|
|
if (lpNBox->lpszText != NULL)
|
|
{
|
|
if (StrDupFree(lpNBox->lpszText) != 0)
|
|
fSuccess = TraceFALSE(NULL);
|
|
else
|
|
lpNBox->lpszText = NULL;
|
|
}
|
|
|
|
// set new text
|
|
//
|
|
if ((lpNBox->lpszText = StrDup(lpszText)) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
}
|
|
|
|
// update the display
|
|
//
|
|
if (fSuccess)
|
|
{
|
|
|
|
RECT rc;
|
|
|
|
// assume entire client area needs to be painted
|
|
//
|
|
GetClientRect(lpNBox->hwndNBox, &rc);
|
|
|
|
// adjust client rect so cancel button is no repainted
|
|
//
|
|
if (lpNBox->dwFlags & NB_CANCEL)
|
|
{
|
|
int cyCancel = (14 * (int) HIWORD(GetDialogBaseUnits())) / 8;
|
|
rc.bottom -= cyCancel * 2;
|
|
}
|
|
|
|
InvalidateRect(lpNBox->hwndNBox, &rc, TRUE);
|
|
UpdateWindow(lpNBox->hwndNBox);
|
|
}
|
|
}
|
|
|
|
return fSuccess ? 0 : -1;
|
|
}
|
|
|
|
// NBoxIsCancelled - get cancel flag, set when Cancel button pushed
|
|
// <hNBox> (i) handle returned from NBoxCreate
|
|
// return TRUE if notify box Cancel button pushed
|
|
//
|
|
BOOL DLLEXPORT WINAPI NBoxIsCancelled(HNBOX hNBox)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPNBOX lpNBox;
|
|
|
|
if ((lpNBox = NBoxGetPtr(hNBox)) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
return fSuccess ? lpNBox->fCancelled : FALSE;
|
|
}
|
|
|
|
// NBoxSetCancelled - set cancel flag
|
|
// <hNBox> (i) handle returned from NBoxCreate
|
|
// <fCancelled> (i) new value for cancel flag
|
|
// return 0 if success
|
|
//
|
|
int DLLEXPORT WINAPI NBoxSetCancelled(HNBOX hNBox, BOOL fCancelled)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPNBOX lpNBox;
|
|
|
|
if ((lpNBox = NBoxGetPtr(hNBox)) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else
|
|
lpNBox->fCancelled = fCancelled;
|
|
|
|
return fSuccess ? 0 : -1;
|
|
}
|
|
|
|
////
|
|
// helper functions
|
|
////
|
|
|
|
// NBoxWndProc - window procedure for notify box
|
|
//
|
|
LRESULT DLLEXPORT CALLBACK NBoxWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LRESULT lResult;
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_NCCREATE:
|
|
lResult = (LRESULT) HANDLE_WM_NCCREATE(hwnd, wParam, lParam, NBoxOnNCCreate);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
lResult = (LRESULT) HANDLE_WM_COMMAND(hwnd, wParam, lParam, NBoxOnCommand);
|
|
break;
|
|
|
|
case WM_PAINT:
|
|
lResult = (LRESULT) HANDLE_WM_PAINT(hwnd, wParam, lParam, NBoxOnPaint);
|
|
break;
|
|
|
|
default:
|
|
lResult = DefWindowProc(hwnd, msg, wParam, lParam);
|
|
break;
|
|
}
|
|
|
|
return lResult;
|
|
}
|
|
|
|
|
|
// NBoxOnNCCreate - handler for WM_NCCREATE message
|
|
//
|
|
static BOOL NBoxOnNCCreate(HWND hwnd, CREATESTRUCT FAR* lpCreateStruct)
|
|
{
|
|
LPNBOX lpNBox = (LPNBOX) lpCreateStruct->lpCreateParams;
|
|
|
|
lpNBox->hwndNBox = hwnd;
|
|
|
|
// store lpNBox in window extra bytes
|
|
//
|
|
SetWindowLongPtr(hwnd, 0, (LONG_PTR) lpNBox);
|
|
|
|
return FORWARD_WM_NCCREATE(hwnd, lpCreateStruct, DefWindowProc);
|
|
}
|
|
|
|
// NBoxOnCommand - handler for WM_COMMAND message
|
|
//
|
|
static void NBoxOnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
|
|
{
|
|
// retrieve lpNBox from window extra bytes
|
|
//
|
|
LPNBOX lpNBox = (LPNBOX) GetWindowLongPtr(hwnd, 0);
|
|
|
|
if (id == IDCANCEL)
|
|
if (codeNotify == BN_CLICKED)
|
|
lpNBox->fCancelled = TRUE;
|
|
|
|
return;
|
|
}
|
|
|
|
// NBoxOnPaint - handler for WM_PAINT message
|
|
//
|
|
static void NBoxOnPaint(HWND hwnd)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
HDC hdc;
|
|
PAINTSTRUCT ps;
|
|
TEXTMETRIC tm;
|
|
int cxChar;
|
|
int cyChar;
|
|
COLORREF crBkColorOld;
|
|
COLORREF crTextColorOld;
|
|
int nRows;
|
|
int nColumns;
|
|
|
|
// retrieve lpNBox from window extra bytes
|
|
//
|
|
LPNBOX lpNBox = (LPNBOX) GetWindowLongPtr(hwnd, 0);
|
|
|
|
hdc = BeginPaint(hwnd, &ps);
|
|
|
|
if (!GetTextMetrics(hdc, &tm))
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else
|
|
{
|
|
cxChar = tm.tmAveCharWidth;
|
|
cyChar = tm.tmHeight + tm.tmExternalLeading;
|
|
|
|
// set foreground and background text colors
|
|
//
|
|
crBkColorOld = SetBkColor(hdc, GetSysColor(COLOR_WINDOW));
|
|
crTextColorOld = SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
|
|
|
|
if (StrGetRowColumnCount(lpNBox->lpszText, &nRows, &nColumns) != 0)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else
|
|
{
|
|
int iRow;
|
|
|
|
for (iRow = 0; iRow < nRows; ++iRow)
|
|
{
|
|
TCHAR szRow[NBOXMAXCOLUMNS + 1];
|
|
|
|
if (StrGetRow(lpNBox->lpszText, iRow, szRow, SIZEOFARRAY(szRow)) != 0)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else
|
|
{
|
|
int x = 5 * cxChar;
|
|
int y = (iRow + 2) * cyChar;
|
|
|
|
if (!TextOut(hdc, x, y, szRow, StrLen(szRow)))
|
|
fSuccess = TraceFALSE(NULL);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Restore foreground and background in the right place
|
|
//
|
|
|
|
// restore foreground and background text colors
|
|
//
|
|
SetBkColor(hdc, crBkColorOld);
|
|
SetTextColor(hdc, crTextColorOld);
|
|
}
|
|
|
|
//
|
|
// Call EndPaint just BeginPaint succeded
|
|
//
|
|
if( hdc )
|
|
EndPaint(hwnd, &ps);
|
|
|
|
return;
|
|
}
|
|
|
|
// NBoxGetPtr - verify that nbox handle is valid,
|
|
// <hNBox> (i) handle returned from NBoxInit
|
|
// return corresponding nbox pointer (NULL if error)
|
|
//
|
|
static LPNBOX NBoxGetPtr(HNBOX hNBox)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
LPNBOX lpNBox;
|
|
|
|
if ((lpNBox = (LPNBOX) hNBox) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
else if (IsBadWritePtr(lpNBox, sizeof(NBOX)))
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
#ifdef CHECKTASK
|
|
// make sure current task owns the nbox handle
|
|
//
|
|
else if (lpNBox->hTask != GetCurrentTask())
|
|
fSuccess = TraceFALSE(NULL);
|
|
#endif
|
|
|
|
return fSuccess ? lpNBox : NULL;
|
|
}
|
|
|
|
// NBoxGetHandle - verify that nbox pointer is valid,
|
|
// <lpNBox> (i) pointer to NBOX struct
|
|
// return corresponding nbox handle (NULL if error)
|
|
//
|
|
static HNBOX NBoxGetHandle(LPNBOX lpNBox)
|
|
{
|
|
BOOL fSuccess = TRUE;
|
|
HNBOX hNBox;
|
|
|
|
if ((hNBox = (HNBOX) lpNBox) == NULL)
|
|
fSuccess = TraceFALSE(NULL);
|
|
|
|
return fSuccess ? hNBox : NULL;
|
|
}
|