home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windoware
/
WINDOWARE_1_6.iso
/
source
/
adg_1-3
/
voyeur.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-21
|
24KB
|
705 lines
/****************************************************************************
Module name: Voyeur.C
Programmer : Jeffrey M. Richter.
*****************************************************************************/
#include "..\nowindws.h"
#undef NOCOLOR
#undef NOCTLMGR
#undef NOGDI
#undef NOKERNEL
#undef NOLSTRING
#undef NOMB
#undef NOMENUS
#undef NOMINMAX
#undef NOMSG
#undef NORASTEROPS
#undef NOSHOWWINDOW
#undef NOSYSMETRICS
#undef NOUSER
#undef NOWINOFFSETS
#undef NOWINMESSAGES
#undef NOWINSTYLES
#include <windows.h>
#include "voyeur.h"
char _szAppName[] = "Voyeur";
HANDLE _hInstance = NULL; // Our instance handle
HWND _hWndStats = NULL;
#define IDM_PEERINTOWINDOW (0x0110) // Must be < 0xF000 (GetSystemMenu)
#define IDM_DROPBACKANDPEER (0x0120) // Must be < 0xF000
#define IDM_ABOUT (0x0130) // Must be < 0xF000
typedef struct { DWORD dwID; char *szName; } STYLELIST;
STYLELIST _ClassStyles[] = {
{ CS_VREDRAW, "VREDRAW" },
{ CS_HREDRAW, "HREDRAW" },
{ CS_KEYCVTWINDOW, "KEYCVTWINDOW" },
{ CS_DBLCLKS, "DBLCLKS" },
{ 0x0010, "OEMCHARS" }, // Windows 2.x
{ CS_OWNDC, "OWNDC" },
{ CS_CLASSDC, "CLASSDC" },
{ CS_PARENTDC, "PARENTDC" },
{ CS_NOKEYCVT, "NOKEYCVT" },
{ CS_NOCLOSE, "NOCLOSE" },
{ CS_SAVEBITS, "SAVEBITS" },
{ CS_BYTEALIGNCLIENT, "BYTEALIGNCLIENT" },
{ CS_BYTEALIGNWINDOW, "BYTEALIGNWINDOW" },
{ CS_GLOBALCLASS, "GLOBALCLASS" },
{ 0, NULL }
};
STYLELIST _WindowStyles[] = {
{ WS_POPUP, "POPUP" },
{ WS_CHILD, "CHILD" },
{ WS_MINIMIZE, "MINIMIZE" },
{ WS_VISIBLE, "VISIBLE" },
{ WS_DISABLED, "DISABLED" },
{ WS_CLIPSIBLINGS, "CLIPSIBLINGS" },
{ WS_CLIPCHILDREN, "CLIPCHILDREN" },
{ WS_MAXIMIZE, "MAXIMIZE" },
{ WS_BORDER, "BORDER" },
{ WS_DLGFRAME, "DLGFRAME" },
{ WS_VSCROLL, "VSCROLL" },
{ WS_HSCROLL, "HSCROLL" },
{ WS_SYSMENU, "SYSMENU" },
{ WS_THICKFRAME, "THICKFRAME" },
{ WS_GROUP, "GROUP, MINIMIZEBOX" },
{ WS_TABSTOP, "TABSTOP, MAXIMIZEBOX" },
{ 0, NULL }
};
STYLELIST _ExtWindowStyles[] = {
{ WS_EX_DLGMODALFRAME, "DLGMODALFRAME" },
{ WS_EX_NOPARENTNOTIFY, "NOPARENTNOTIFY" },
{ 0, NULL }
};
typedef enum {
CIH_ICON, CIH_CURSOR, CIH_BACKGROUND, CIH_WNDPROC, CIH_MENU, CIH_END
} CLASSINFOHEAD;
char *szClassInfoHeading[] = {
"Icon: ",
"Cursor: ",
"Backgrnd: ",
"WndProc: ",
"Menu: ",
NULL
};
BOOL NEAR PASCAL RegisterAppWndClass (HANDLE hInstance);
BOOL FAR PASCAL AboutProc (HWND hDlg, WORD wMsg, WORD wParam, LONG lParam);
BOOL FAR PASCAL ForcePeer (HWND hDlg, WORD wMsg, WORD wParam, LONG lParam);
LONG FAR PASCAL VoyeurAppWndProc (HWND hWnd, WORD wMsg, WORD wParam, LONG lParam);
// ***************************************************************************
int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) {
MSG msg;
HWND hWnd;
_hInstance = hInstance;
if (hPrevInstance == NULL)
if (!RegisterAppWndClass(hInstance))
return(0);
hWnd = CreateWindow(_szAppName, _szAppName,
WS_OVERLAPPED | WS_VISIBLE | WS_CLIPCHILDREN |
WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT, nCmdShow, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, 0);
if (hWnd == NULL) return(0);
while (GetMessage(&msg, NULL, 0, 0)) {
if (!IsDialogMessage(_hWndStats, &msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return(0);
}
// ***************************************************************************
// This function registers Voyeur's main window.
BOOL NEAR PASCAL RegisterAppWndClass (HANDLE hInstance) {
WNDCLASS WndClass;
WndClass.style = 0;
WndClass.lpfnWndProc = VoyeurAppWndProc;
WndClass.cbClsExtra = 0;
WndClass.cbWndExtra = 0;
WndClass.hInstance = hInstance;
WndClass.hIcon = LoadIcon(hInstance, _szAppName);
WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground = COLOR_WINDOW + 1;
WndClass.lpszMenuName = NULL;
WndClass.lpszClassName = _szAppName;
return(RegisterClass(&WndClass));
}
// ***************************************************************************
// This function processes all messages sent to the modeless dialog box.
BOOL FAR PASCAL VoyeurDlgProc (HWND hDlg, WORD wMsg, WORD wParam, LONG lParam) {
BOOL fProcessed = TRUE;
WORD wTextLen, wMaxTextLen = 0, wTabStop;
NPSTR szHeading; HDC hDC;
CLASSINFOHEAD ClassInfoHead;
HWND hWndOtherBox;
switch (wMsg) {
case WM_INITDIALOG:
// Determine where to place tabstop in listbox.
hWndOtherBox = GetDlgItem(hDlg, ID_CLASSOTHERBOX);
hDC = GetDC(hWndOtherBox);
for (ClassInfoHead = 0; ClassInfoHead != CIH_END; ClassInfoHead++) {
szHeading = szClassInfoHeading[ClassInfoHead];
// Get length (in pixels) of heading.
wTextLen = LOWORD(GetTextExtent(hDC, szHeading,
lstrlen(szHeading)));
// Find heading with maximum length.
wMaxTextLen = max(wMaxTextLen, wTextLen);
}
ReleaseDC(hWndOtherBox, hDC);
// Convert pixels into dialog units.
wTabStop = 4 + wMaxTextLen / (LOWORD(GetDialogBaseUnits()) / 4);
// Set tabstop position in listbox. Note: listbox must have
// LBS_USETABSTOPS style in dialog box template.
SendMessage(hWndOtherBox, LB_SETTABSTOPS, 1,
(LONG) (WORD FAR *) &wTabStop);
fProcessed = FALSE;
break;
default:
fProcessed = FALSE;
break;
}
return(fProcessed);
}
// ***************************************************************************
// This function fills a listbox with the text names of the styles.
// It is used for the class styles, window styles, and extended
// window styles.
void NEAR PASCAL FillStyleBox (HWND hListBox, STYLELIST Styles[],
DWORD dwStyleFlags) {
int x;
// Turn off redraw so that the listbox will not flicker every time
// an entry is added to it. This also makes updating much faster.
SendMessage(hListBox, WM_SETREDRAW, FALSE, 0);
// Empty the listbox.
SendMessage(hListBox, LB_RESETCONTENT, 0, 0);
for (x = 0; Styles[x].szName != NULL; x++) {
if (Styles[x].dwID & dwStyleFlags) {
// If the style bit is set, add the style text to the listbox.
SendMessage(hListBox, LB_ADDSTRING, 0,
(LONG) (LPSTR) Styles[x].szName);
}
}
// Turn redraw back on.
SendMessage(hListBox, WM_SETREDRAW, TRUE, 0);
// Force redraw of listbox so that screen shows proper information.
InvalidateRect(hListBox, NULL, TRUE);
}
// ***************************************************************************
// This function sets all of the static and listbox windows with the class
// information about the passed-in window (hWnd).
void NEAR PASCAL SetClassInfo (HWND hDlg, HWND hWnd) {
char szText[100], szBuf[100];
WNDCLASS WndClass;
WORD x;
// Get the class name of the window.
GetClassName(hWnd, szBuf, sizeof(szBuf));
SetDlgItemText(hDlg, ID_CLASSNAME, szBuf);
// Fill a WNDCLASS structure.
GetClassInfo(GetClassWord(hWnd, GCW_HMODULE), szBuf, &WndClass);
WndClass.hInstance = GetClassWord(hWnd, GCW_HMODULE);
// Get the module name of the application that registered this class.
GetModuleFileName(WndClass.hInstance, szText, sizeof(szText));
wsprintf(szBuf, "0x%04X, %s", WndClass.hInstance, (LPSTR) szText);
SetDlgItemText(hDlg, ID_OWNER, szBuf);
// Fill the "Other" listbox with information from WNDCLASS structure.
SendDlgItemMessage(hDlg, ID_CLASSOTHERBOX, WM_SETREDRAW, FALSE, 0);
SendDlgItemMessage(hDlg, ID_CLASSOTHERBOX, LB_RESETCONTENT, 0, 0);
wsprintf(szBuf, "%s\t0x%04X",
(LPSTR) szClassInfoHeading[CIH_ICON], WndClass.hIcon);
SendDlgItemMessage(hDlg, ID_CLASSOTHERBOX, LB_ADDSTRING, 0,
(LONG) (LPSTR) szBuf);
wsprintf(szBuf, "%s\t0x%04X",
(LPSTR) szClassInfoHeading[CIH_CURSOR], WndClass.hCursor);
SendDlgItemMessage(hDlg, ID_CLASSOTHERBOX, LB_ADDSTRING, 0,
(LONG) (LPSTR) szBuf);
wsprintf(szBuf, "%s\t0x%04X",
(LPSTR) szClassInfoHeading[CIH_BACKGROUND], WndClass.hbrBackground);
SendDlgItemMessage(hDlg, ID_CLASSOTHERBOX, LB_ADDSTRING, 0,
(LONG) (LPSTR) szBuf);
wsprintf(szBuf, "%s\t0x%04X:0x%04X",
(LPSTR) szClassInfoHeading[CIH_WNDPROC],
HIWORD(WndClass.lpfnWndProc), LOWORD((LONG) WndClass.lpfnWndProc));
SendDlgItemMessage(hDlg, ID_CLASSOTHERBOX, LB_ADDSTRING, 0,
(LONG) (LPSTR) szBuf);
wsprintf(szBuf, "%s\t0x%04X:0x%04X",
(LPSTR) szClassInfoHeading[CIH_MENU],
HIWORD(WndClass.lpszMenuName), LOWORD((LONG) WndClass.lpszMenuName));
SendDlgItemMessage(hDlg, ID_CLASSOTHERBOX, LB_ADDSTRING, 0,
(LONG) (LPSTR) szBuf);
SendDlgItemMessage(hDlg, ID_CLASSOTHERBOX, WM_SETREDRAW, TRUE, 0);
InvalidateRect(GetDlgItem(hDlg, ID_CLASSOTHERBOX), NULL, TRUE);
// Fill in all the "Class style" information.
wsprintf(szBuf, "0x%04X", WndClass.style);
SetDlgItemText(hDlg, ID_CLASSSTYLE, szBuf);
// Fill the "Class style" listbox with information from WndClass.style.
FillStyleBox(GetDlgItem(hDlg, ID_CLASSSTYLEBOX),
_ClassStyles, WndClass.style);
// Fill in all the "Class extra byte" information.
wsprintf(szBuf, "%d", WndClass.cbClsExtra);
SetDlgItemText(hDlg, ID_CBCLSEXTRA, szBuf);
// Fill the "Class extra bytes" listbox.
SendDlgItemMessage(hDlg, ID_CBCLSEXTRABOX, WM_SETREDRAW, FALSE, 0);
SendDlgItemMessage(hDlg, ID_CBCLSEXTRABOX, LB_RESETCONTENT, 0, 0);
for (x = 0; x < (WORD) WndClass.cbClsExtra; x++) {
wsprintf(szBuf, "%02d) 0x%02X", x, LOBYTE(GetClassWord(hWnd, x)));
SendDlgItemMessage(hDlg, ID_CBCLSEXTRABOX, LB_ADDSTRING, 0,
(LONG) (LPSTR) szBuf);
}
SendDlgItemMessage(hDlg, ID_CBCLSEXTRABOX, WM_SETREDRAW, TRUE, 0);
// Force redraw of "Class extra bytes" listbox.
InvalidateRect(GetDlgItem(hDlg, ID_CBCLSEXTRABOX), NULL, TRUE);
}
// ***************************************************************************
// This function sets all of the static and listbox windows with the window
// information about the passed-in window (hWnd).
void NEAR PASCAL SetWindowInfo (HWND hDlg, HWND hWnd) {
char szText[100], szBuf[100];
HANDLE hInstance;
FARPROC lpfnWndProc;
HWND hWndParent;
RECT rc;
WORD x, cbWndExtra;
// Get caption of "peered" window.
if (GetWindowText(hWnd, szText, sizeof(szText)) == 0)
lstrcpy(szText, "(no caption)");
wsprintf(szBuf, "0x%04X, %s", hWnd, (LPSTR) szText);
SetDlgItemText(hDlg, ID_WINDOW, szBuf);
// Get module name of application that created this window.
hInstance = GetWindowWord(hWnd, GWW_HINSTANCE);
if (GetModuleFileName(hInstance, szText, sizeof(szText)) == 0)
lstrcpy(szText, "(no module name)");
wsprintf(szBuf, "0x%04X, %s", hInstance, (LPSTR) szText);
SetDlgItemText(hDlg, ID_CREATOR, szBuf);
// If window has a parent, get the parent's information.
hWndParent = GetParent(hWnd);
if (hWndParent == NULL)
lstrcpy(szBuf, "(no parent window)");
else {
if (GetWindowText(hWndParent, szText, sizeof(szText)) == 0)
lstrcpy(szText, "(no caption)");
wsprintf(szBuf, "0x%04X, %s", hWndParent, (LPSTR) szText);
}
SetDlgItemText(hDlg, ID_PARENT, szBuf);
// Get address of window's window procedure.
lpfnWndProc = (FARPROC) GetWindowLong(hWnd, GWL_WNDPROC);
wsprintf(szBuf, "0x%04X:0x%04X",
HIWORD(lpfnWndProc), LOWORD((LONG) lpfnWndProc));
SetDlgItemText(hDlg, ID_WNDPROC, szBuf);
// Get window's ID.
wsprintf(szBuf, "0x%04X (%d)", GetWindowWord(hWnd, GWW_ID),
GetWindowWord(hWnd, GWW_ID));
SetDlgItemText(hDlg, ID_ID, szBuf);
// Get screen coordinates of window.
// Show (left, top)-(right, bottom), Dim=Width x Height
GetWindowRect(hWnd, &rc);
wsprintf(szBuf, "(%d, %d)-(%d, %d), Dim=%dx%d",
rc.left, rc.top, rc.right, rc.bottom,
rc.right - rc.left, rc.bottom - rc.top);
SetDlgItemText(hDlg, ID_LOCATION, szBuf);
// Fill in all the "Window style" information.
wsprintf(szBuf, "0x%08lX", GetWindowLong(hWnd, GWL_STYLE));
SetDlgItemText(hDlg, ID_WNDSTYLES, szBuf);
// Fill the "Window style" listbox.
FillStyleBox(GetDlgItem(hDlg, ID_WNDSTYLESBOX),
_WindowStyles, GetWindowLong(hWnd, GWL_STYLE));
// Fill in all the "Extended window style" information.
wsprintf(szBuf, "0x%08lX", GetWindowLong(hWnd, GWL_EXSTYLE));
SetDlgItemText(hDlg, ID_WNDEXTSTYLES, szBuf);
// Fill the "Extended window style" listbox.
FillStyleBox(GetDlgItem(hDlg, ID_WNDEXTSTYLESBOX),
_ExtWindowStyles, GetWindowLong(hWnd, GWL_EXSTYLE));
// Fill in all the "Window extra byte" information.
cbWndExtra = GetClassWord(hWnd, GCW_CBWNDEXTRA);
wsprintf(szBuf, "%d", cbWndExtra);
SetDlgItemText(hDlg, ID_CBWNDEXTRA, szBuf);
// Fill the "Window extra bytes" listbox.
SendDlgItemMessage(hDlg, ID_CBWNDEXTRABOX, WM_SETREDRAW, FALSE, 0);
SendDlgItemMessage(hDlg, ID_CBWNDEXTRABOX, LB_RESETCONTENT, 0, 0);
for (x = 0; x < cbWndExtra; x++) {
wsprintf(szBuf, "%02d) 0x%02X", x, LOBYTE(GetWindowWord(hWnd, x)));
SendDlgItemMessage(hDlg, ID_CBWNDEXTRABOX, LB_ADDSTRING, 0,
(LONG) (LPSTR) szBuf);
}
SendDlgItemMessage(hDlg, ID_CBWNDEXTRABOX, WM_SETREDRAW, TRUE, 0);
// Force redraw of "Window extra bytes" listbox.
InvalidateRect(GetDlgItem(hDlg, ID_CBWNDEXTRABOX), NULL, TRUE);
}
// ***************************************************************************
// This functions draw a frame around a given window. The frame is drawn
// in the inverse screen color. This allows a second call to this function
// to restore the screen display to its original appearance.
void NEAR PASCAL DrawWindowFrame (HWND hWnd) {
HDC hDC;
RECT rc;
HPEN hPen;
// Retrieve location of window on screen
GetWindowRect(hWnd, &rc);
// Get a Device context that allows us to write anywhere within the
// window. NOTE: GetDC would only allow us to write in the window's
// client area.
hDC = GetWindowDC(hWnd);
// To guarantee that the frame will be visible, tell Windows to
// draw the frame using the inverse screen color.
SetROP2(hDC, R2_NOT);
// Create a pen that is 3 times the width on a non-sizeable border
// think. The color will not be used to draw the frame, so its
// value could be anything. PS_INSIDEFRAME tells windows that the
// entire frame should be enclosed within the window.
hPen = CreatePen(PS_INSIDEFRAME, 3 * GetSystemMetrics(SM_CXBORDER),
RGB(0, 0, 0));
SelectObject(hDC, hPen);
// We must select a NULL brush so that the contents of the window
// will not be covered.
SelectObject(hDC, GetStockObject(NULL_BRUSH));
// Draw the frame. Because the Device Context is relative to
// the window, the left-top corner is (0, 0) and the right-bottom
// corner is (width of window, height of window)
Rectangle(hDC, 0, 0, rc.right - rc.left, rc.bottom - rc.top);
ReleaseDC(hWnd, hDC);
// We can only destroy the pen AFTER we have released the Device Context
// because the DC must have valid "tools" in it at all times.
DeleteObject(hPen);
}
// ***************************************************************************
// This function processes all messages sent to Voyeur's main window.
LONG FAR PASCAL VoyeurAppWndProc (HWND hWnd, WORD wMsg, WORD wParam, LONG lParam) {
BOOL fOk, fCallDefProc = FALSE;
LONG lResult = 0;
HMENU hMenu;
RECT rc, rcStatDlg;
FARPROC fpProc;
HWND hWndSubject, hWndChild;
static HWND hWndLastSubject = NULL;
switch (wMsg) {
case WM_NCCREATE:
// Allow Windows to allocate memory for window.
fOk = (BOOL) DefWindowProc(hWnd, wMsg, wParam, lParam);
if (!fOk) {
// Windows couldn't create the window, return.
lResult = 0;
break;
}
// Try to create modeless dialog box.
_hWndStats = CreateDialog(_hInstance, "VOYEUR", hWnd,
MakeProcInstance(VoyeurDlgProc, _hInstance));
if (_hWndStats == NULL) {
// If modeless dialog box couldn't be created, tell
// Windows to free memory for window and return.
DefWindowProc(hWnd, WM_NCDESTROY, 0, 0);
lResult = 0;
break;
}
// Change Voyeur's window dimensions so that it exactly
// surrounds the modeless dialog box. Voyeur's position
// on the screen should not be altered.
GetWindowRect(hWnd, &rc);
GetWindowRect(_hWndStats, &rcStatDlg);
MoveWindow(hWnd, rc.left, rc.top,
rcStatDlg.right - rcStatDlg.left,
rcStatDlg.bottom - rcStatDlg.top + GetSystemMetrics(SM_CYCAPTION),
FALSE);
// Get handle to Voyeur's System Menu.
hMenu = GetSystemMenu(hWnd, 0);
// Append separator bar & two options.
AppendMenu(hMenu, MF_SEPARATOR, 0, 0);
AppendMenu(hMenu, MF_STRING,
IDM_PEERINTOWINDOW, "&Peer into window");
AppendMenu(hMenu, MF_STRING,
IDM_DROPBACKANDPEER, "&Drop back and peer");
// Append separator bar & "About..." option.
AppendMenu(hMenu, MF_SEPARATOR, 0, 0);
AppendMenu(hMenu, MF_STRING, IDM_ABOUT, "A&bout...");
DrawMenuBar(hWnd);
lResult = 1; // Window has been created OK.
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_SYSCOMMAND:
// Any menu option selected from Voyeur's System Menu.
// Any option's that we appended to System menu should be
// processed by Voyeur and NOT passed to DefWindowProc.
switch (wParam & 0xfff0) {
case IDM_ABOUT:
// Display Voyeur's about box
fpProc = MakeProcInstance(AboutProc, _hInstance);
DialogBox(_hInstance, "About", hWnd, fpProc);
FreeProcInstance(fpProc);
break;
case IDM_DROPBACKANDPEER:
// Send Voyeur's window to back of Window Manager's list
// This causes any windows that are overlapped by Voyeur
// to become visible. This allows these windows to be
// "peered" into.
SetWindowPos(hWnd, 1, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
// Fall through to IDM_PEERINTOWINDOW
case IDM_PEERINTOWINDOW:
// Force all mouse messages to arrive at this window procedure.
SetCapture(hWnd);
// Change the mouse cursor to a pair of eyes. This provides a
// visual indication to the user that Voyeur is in "peer" mode.
SetCursor(LoadCursor(_hInstance, "Eyes"));
// Set the Window handle of the last viewed window to NULL.
hWndLastSubject = NULL;
break;
default:
// Any option's that we do not process should be
// passed to DefWindowProc.
fCallDefProc = TRUE;
break;
}
break;
case WM_MOUSEMOVE:
// If we don't have capture, we shouldn't do anything.
if (GetCapture() == NULL)
break;
// lParam contains the mouse location relative to Voyeur's
// client area.
// Convert the location to screen coordinates
ClientToScreen(hWnd, &MAKEPOINT(lParam));
// Get the window handle of the window under the mouse cursor.
hWndSubject = WindowFromPoint(MAKEPOINT(lParam));
// If mouse isn't over a window, return
if (hWndSubject == NULL) break;
// If window as created by Voyeur, ignore it.
if (GetWindowTask(hWndSubject) == GetCurrentTask())
break;
// Convert the mouse location into client coordinates relative
// to the window that is under the mouse cursor.
ScreenToClient(hWndSubject, &MAKEPOINT(lParam));
// Get the window handle of the child window under the mouse cursor.
hWndChild = ChildWindowFromPoint(hWndSubject, MAKEPOINT(lParam));
// If point is over a child, our subject is the child window
if (hWndChild != NULL)
hWndSubject = hWndChild;
// If our new subject is the same as our last subject, there is
// no need to update our display.
if (hWndLastSubject == hWndSubject)
break;
// If this is not our first window being viewed, remove the
// frame surrounding the previously viewed window.
if (hWndLastSubject != NULL)
DrawWindowFrame(hWndLastSubject);
UpdateWindow(hWndSubject);
// Draw a frame around our new window.
DrawWindowFrame(hWndSubject);
// Fill our status box with the subject window's class information.
SetClassInfo(_hWndStats, hWndSubject);
// Fill our status box with the subject window's window information.
SetWindowInfo(_hWndStats, hWndSubject);
hWndLastSubject = hWndSubject;
break;
case WM_LBUTTONUP:
// If we don't have capture, we shouldn't do anything.
if (GetCapture() != hWnd)
break;
// If we never "peered" into a window, we don't have to remove
// its surrounding frame.
if (hWndLastSubject != NULL)
DrawWindowFrame(hWndLastSubject);
// Allow other applications to receive mouse messages.
ReleaseCapture();
// Force Voyeur to appear on top of all other windows.
BringWindowToTop(hWnd);
break;
default:
fCallDefProc = TRUE; break;
}
if (fCallDefProc)
lResult = DefWindowProc(hWnd, wMsg, wParam, lParam);
return(lResult);
}
// ***************************************************************************
// This function processes all messages sent to the About dialog box.
BOOL FAR PASCAL AboutProc (HWND hDlg, WORD wMsg, WORD wParam, LONG lParam) {
char szBuffer[100];
BOOL fProcessed = TRUE;
switch (wMsg) {
case WM_INITDIALOG:
// Set version static window to have date and time of compilation.
wsprintf(szBuffer, "%s at %s", (LPSTR) __DATE__, (LPSTR) __TIME__);
SetWindowText(GetDlgItem(hDlg, ID_VERSION), szBuffer);
break;
case WM_COMMAND:
switch (wParam) {
case IDOK: case IDCANCEL:
if (HIWORD(lParam) == BN_CLICKED)
EndDialog(hDlg, wParam);
break;
default:
break;
}
break;
default:
fProcessed = FALSE; break;
}
return(fProcessed);
}