summaryrefslogtreecommitdiffstats
path: root/private/sdktools/ddespy
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/sdktools/ddespy
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to '')
-rw-r--r--private/sdktools/ddespy/ddespy.c1312
-rw-r--r--private/sdktools/ddespy/ddespy.def32
-rw-r--r--private/sdktools/ddespy/ddespy.dlg75
-rw-r--r--private/sdktools/ddespy/ddespy.h333
-rw-r--r--private/sdktools/ddespy/ddespy.icobin0 -> 1086 bytes
-rw-r--r--private/sdktools/ddespy/ddespy.rc186
-rw-r--r--private/sdktools/ddespy/dialog.h10
-rw-r--r--private/sdktools/ddespy/globals.h27
-rw-r--r--private/sdktools/ddespy/lists.c433
-rw-r--r--private/sdktools/ddespy/lists.h35
-rw-r--r--private/sdktools/ddespy/makefile6
-rw-r--r--private/sdktools/ddespy/sources20
-rw-r--r--private/sdktools/ddespy/testsubs.c344
13 files changed, 2813 insertions, 0 deletions
diff --git a/private/sdktools/ddespy/ddespy.c b/private/sdktools/ddespy/ddespy.c
new file mode 100644
index 000000000..3a8ae024e
--- /dev/null
+++ b/private/sdktools/ddespy/ddespy.c
@@ -0,0 +1,1312 @@
+/****************************************************************************
+
+ PROGRAM: DdeSpy.c
+
+****************************************************************************/
+
+#define UNICODE
+#include <windows.h> /* required for all Windows applications */
+#include <windowsx.h>
+#include <shellapi.h>
+#include <dde.h>
+#include <stdio.h>
+#include <io.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "ddespy.h"
+#include "lists.h"
+
+/* GLOBAL Variables used for DDESPY */
+
+UINT idInst = 0;
+HINSTANCE hInst;
+HICON hIcon;
+HWND hWndString = NULL;
+HWND hwndSpy = NULL;
+HANDLE fhOutput = NULL;
+OFSTRUCT ofsOpen;
+TCHAR OpenName[MAX_FNAME + 1];
+TCHAR TBuf[BUFFER_SIZE];
+TCHAR TBuf2[BUFFER_SIZE];
+TCHAR szNULL[] = TEXT("");
+LPTSTR apszResources[IDS_LAST + 1];
+PFNCALLBACK pfnDdeCallback = NULL;
+HWND hwndTrack[IT_COUNT] = { 0 };
+LPTSTR TrackTitle[IT_COUNT];
+BOOL fBlockMsg[WM_DDE_LAST - WM_DDE_FIRST + 1] = { 0 };
+BOOL fBlockCb[15] = { 0 };
+LPTSTR TrackHeading[IT_COUNT];
+struct { /* profile data */
+ BOOL fOutput[IO_COUNT];
+ BOOL fFilter[IF_COUNT];
+ BOOL fTrack[IT_COUNT];
+ BOOL fTerse;
+} pro;
+
+
+
+BOOL LoadResourceStrings()
+{
+ int i, cbLeft, cbRes;
+ LPTSTR psz;
+
+ cbLeft = 0x1000;
+ psz = LocalAlloc(LPTR, sizeof(TCHAR) * cbLeft);
+ for (i = 0; i <= IDS_LAST; i++) {
+ apszResources[i] = psz;
+ cbRes = LoadString(hInst, i, psz, cbLeft) + 1;
+ cbLeft -= cbRes;
+ psz += cbRes;
+ }
+ for (i = 0; i < IT_COUNT; i++) {
+ TrackTitle[i] = RefString(IDS_TRACKTITLE_1 + i);
+ TrackHeading[i] = RefString(IDS_TRACKHEADING_1 + i);
+ }
+ lstrcpy(TBuf, RefString(IDS_DEFAULT_OUTPUT_FNAME));
+ GetFullPathName(TBuf, sizeof(OpenName) / sizeof(TCHAR),
+ OpenName, (LPTSTR *)TBuf2);
+ return(TRUE);
+}
+
+
+
+int WINAPI WinMain(
+ HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nCmdShow)
+{
+ MSG msg;
+
+ UNREFERENCED_PARAMETER(lpCmdLine);
+
+ hInst = hInstance;
+
+ if (!LoadResourceStrings()) {
+ return (FALSE);
+ }
+
+ if (!hPrevInstance)
+ if (!InitApplication(hInstance)) /* Initialize shared things */
+ return (FALSE); /* Exits if unable to initialize */
+
+ /* Perform initializations that apply to a specific instance */
+
+ if (!InitInstance(hInstance, nCmdShow)) {
+ CloseApp();
+ return (FALSE);
+ }
+
+ /* Acquire and dispatch messages until a WM_QUIT message is received. */
+
+ while (GetMessage(&msg, /* message structure */
+ NULL, /* handle of window receiving the message */
+ 0, /* lowest message to examine */
+ 0)) /* highest message to examine */
+ {
+ TranslateMessage(&msg); /* Translates virtual key codes */
+ DispatchMessage(&msg); /* Dispatches message to window */
+ }
+ CloseApp();
+ return (msg.wParam); /* Returns the value from PostQuitMessage */
+}
+
+
+
+BOOL InitApplication(HINSTANCE hInstance)
+{
+ WNDCLASS wc;
+
+ if (!InitTestSubs())
+ return(FALSE);
+
+ /* Fill in window class structure with parameters that describe the */
+ /* main window. */
+
+ wc.style = 0; /* Class style(s). */
+ wc.lpfnWndProc = (WNDPROC)MainWndProc; /* Function to retrieve messages for */
+ /* windows of this class. */
+ wc.cbClsExtra = 0; /* No per-class extra data. */
+ wc.cbWndExtra = 0; /* No per-window extra data. */
+ wc.hInstance = hInstance; /* Application that owns the class. */
+ /* faster, also can localize "DDESpy" */
+ hIcon = wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DDESPY));
+ wc.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wc.hbrBackground = GetStockObject(WHITE_BRUSH);
+ wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU); /* Name of menu resource in .RC file. */
+ wc.lpszClassName = RefString(IDS_CLASS);
+
+ /* Register the window class and return success/failure code. */
+
+ return (RegisterClass(&wc));
+}
+
+
+BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
+{
+ RECT Rect;
+ INT i;
+
+ /* Save the instance handle in static variable, which will be used in */
+ /* many subsequence calls from this application to Windows. */
+
+ pfnDdeCallback = (PFNCALLBACK)MakeProcInstance((FARPROC)DdeCallback,
+ hInstance);
+
+ GetProfile();
+
+ /* Create a main window for this application instance. */
+
+ hwndSpy = CreateWindow(
+ RefString(IDS_CLASS),
+ RefString(IDS_TITLE),
+ WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
+ CW_USEDEFAULT, /* Default horizontal position. */
+ CW_USEDEFAULT, /* Default vertical position. */
+ CW_USEDEFAULT, /* Default width. */
+ CW_USEDEFAULT, /* Default height. */
+ NULL, /* Overlapped windows have no parent. */
+ NULL, /* Use the window class menu. */
+ hInstance, /* This instance owns this window. */
+ NULL /* Pointer not needed. */
+ );
+
+
+ GetClientRect(hwndSpy, (LPRECT) &Rect);
+
+ hWndString = CreateWindow( /* String Window (class Registered in Teststubs)*/
+ RefString(IDS_STRINGCLASS),
+ szNULL,
+ WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL,
+ 0,
+ 0,
+ Rect.right - Rect.left,
+ Rect.bottom - Rect.top,
+ hwndSpy,
+ NULL,
+ hInst,
+ (LPTSTR)MAKELONG(CCHARS, CLINES));
+
+ for (i = 0; i < IT_COUNT; i++) {
+ if (pro.fTrack[i]) {
+ pro.fTrack[i] = FALSE;
+ SendMessage(hwndSpy, WM_COMMAND,
+ GET_WM_COMMAND_MPS(IDM_TRACK_FIRST + i, 0, 0));
+ }
+ }
+
+ if (!hwndSpy || !hWndString) {
+ CloseApp();
+ return (FALSE);
+ }
+
+ /* Make the window visible; update its client area; and return "success" */
+
+ ShowWindow(hwndSpy, nCmdShow); /* Show the window */
+ UpdateWindow(hwndSpy); /* Sends WM_PAINT message */
+
+ if (SetFilters()) {
+ return(FALSE);
+ }
+
+ return(TRUE);
+}
+
+
+VOID CloseApp()
+{
+ DdeUninitialize(idInst); /* perform cleanup and store profile */
+ SaveProfile();
+ if (fhOutput != NULL)
+ CloseHandle(fhOutput);
+ UnregisterClass(RefString(IDS_CLASS), hInst);
+ CloseTestSubs(hInst);
+}
+
+
+
+LONG CALLBACK MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ int i;
+
+ switch (message) {
+ case WM_CREATE:
+ LoadAccelerators(hInst, MAKEINTRESOURCE(IDR_ACCEL));
+ if (pro.fOutput[IO_FILE])
+ fhOutput = (HANDLE)DoDialog(
+ MAKEINTRESOURCE(IDD_OPEN),
+ (DLGPROC)OpenDlg,
+ 0,
+ TRUE,
+ hWnd,
+ hInst);
+ pro.fOutput[IO_FILE] = (fhOutput != NULL);
+ break;
+
+ case WM_INITMENU:
+ if (GetMenu(hWnd) != (HMENU)wParam)
+ break;
+
+ for (i = 0; i < IO_COUNT; i++) {
+ CheckMenuItem((HMENU)wParam, IDM_OUTPUT_FIRST + i,
+ pro.fOutput[i] ? MF_CHECKED : MF_UNCHECKED);
+ }
+
+ for (i = 0; i < IF_COUNT; i++) {
+ CheckMenuItem((HMENU)wParam, IDM_FILTER_FIRST + i,
+ pro.fFilter[i] ? MF_CHECKED : MF_UNCHECKED);
+ }
+
+ for (i = 0; i < IT_COUNT; i++) {
+ CheckMenuItem((HMENU)wParam, IDM_TRACK_FIRST + i,
+ pro.fTrack[i] ? MF_CHECKED : MF_UNCHECKED);
+ }
+ break;
+
+ case WM_COMMAND: /* message: command from application menu */
+ switch (GET_WM_COMMAND_ID(wParam, lParam)) {
+ case IDM_OUTPUT_FILE:
+ case IDM_OUTPUT_DEBUG:
+ case IDM_OUTPUT_SCREEN:
+ switch (wParam) {
+ case IDM_OUTPUT_FILE:
+ if (fhOutput != NULL) {
+ wsprintf(TBuf, RefString(IDS_QCLOSEFILE_TEXT), OpenName);
+ if (IDYES != MessageBox(hWnd,
+ TBuf, RefString(IDS_QCLOSEFILE_CAPTION),
+ MB_YESNO | MB_ICONQUESTION)) {
+ break;
+ }
+ CloseHandle(fhOutput);
+ }
+ fhOutput = (HANDLE)DoDialog(
+ MAKEINTRESOURCE(IDD_OPEN),
+ (DLGPROC)OpenDlg,
+ 0,
+ TRUE,
+ hWnd,
+ hInst);
+ pro.fOutput[IO_FILE] = (fhOutput != NULL);
+ break;
+
+ case IDM_OUTPUT_DEBUG:
+ pro.fOutput[IO_DEBUG] = !pro.fOutput[IO_DEBUG];
+ break;
+
+ case IDM_OUTPUT_SCREEN:
+ pro.fOutput[IO_SCREEN] = !pro.fOutput[IO_SCREEN];
+ break;
+
+ }
+ break;
+
+ case IDM_CLEARSCREEN:
+ if (hWndString) {
+ HANDLE hpsw;
+ STRWND *psw;
+
+ hpsw = (HANDLE)GetWindowLong(hWndString, 0);
+ psw = (STRWND *)LocalLock(hpsw);
+ ClearScreen(psw);
+ LocalUnlock(hpsw);
+ InvalidateRect(hWndString, NULL, TRUE);
+ }
+ break;
+
+ case IDM_MARK:
+ DoDialog(MAKEINTRESOURCE(IDD_VALUEENTRY), (DLGPROC)MarkDlgProc, 0, TRUE, hWnd, hInst);
+ break;
+
+ case IDM_FILTER_HSZINFO:
+ case IDM_FILTER_INIT_TERM:
+ case IDM_FILTER_DDEMSGS:
+ case IDM_FILTER_CALLBACKS:
+ case IDM_FILTER_ERRORS:
+ pro.fFilter[wParam - IDM_FILTER_FIRST] =
+ !pro.fFilter[wParam - IDM_FILTER_FIRST];
+ SetFilters();
+ break;
+
+ case IDM_FILTER_DIALOG:
+ DoDialog(MAKEINTRESOURCE(IDD_MSGFILTERS), (DLGPROC)FilterDlgProc, 0, TRUE, hWnd, hInst);
+ break;
+
+ case IDM_TRACK_HSZS:
+ case IDM_TRACK_CONVS:
+ case IDM_TRACK_LINKS:
+ case IDM_TRACK_SVRS:
+ pro.fTrack[wParam - IDM_TRACK_FIRST] =
+ !pro.fTrack[wParam - IDM_TRACK_FIRST];
+ if (pro.fTrack[wParam - IDM_TRACK_FIRST]) {
+ hwndTrack[wParam - IDM_TRACK_FIRST] = CreateMCLBFrame(
+ NULL,
+ TrackTitle[wParam - IDM_TRACK_FIRST],
+ WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_MINIMIZE,
+ hIcon, (HBRUSH)(COLOR_APPWORKSPACE + 1),
+ TrackHeading[wParam - IDM_TRACK_FIRST]);
+ } else {
+ DestroyWindow(hwndTrack[wParam - IDM_TRACK_FIRST]);
+ hwndTrack[wParam - IDM_TRACK_FIRST] = 0;
+ }
+ SetFilters();
+ break;
+
+ case IDM_ABOUT:
+ DoDialog(MAKEINTRESOURCE(IDD_ABOUTBOX), (DLGPROC)About, 0, TRUE, hWnd, hInst);
+ break;
+
+ default:
+ return (DefWindowProc(hWnd, message, wParam, lParam));
+ }
+ break;
+
+ case WM_DESTROY: /* message: window being destroyed */
+ for (i = IDM_TRACK_FIRST; i <= IDM_TRACK_LAST; i++) {
+ if (pro.fTrack[i - IDM_TRACK_FIRST]) {
+ DestroyWindow(hwndTrack[i - IDM_TRACK_FIRST]);
+ hwndTrack[i - IDM_TRACK_FIRST] = 0;
+ }
+ }
+ PostQuitMessage(0);
+ break;
+
+ case WM_SIZE:
+ if (hWndString) {
+ RECT rc;
+
+ GetClientRect(hWnd, &rc);
+ MoveWindow(hWndString, 0, 0, rc.right, rc.bottom, TRUE);
+ }
+ // fall through
+ default:
+ return (DefWindowProc(hWnd, message, wParam, lParam));
+ }
+ return (0);
+}
+
+
+
+
+
+BOOL CALLBACK About(
+ HWND hDlg,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ switch (message) {
+ case WM_INITDIALOG: /* message: initialize dialog box */
+ return (TRUE);
+
+ case WM_COMMAND: /* message: received a command */
+ if (GET_WM_COMMAND_ID(wParam, lParam) == IDOK
+ || GET_WM_COMMAND_ID(wParam, lParam) == IDCANCEL) {
+ EndDialog(hDlg, TRUE); /* Exits the dialog box */
+ return (TRUE);
+ }
+ break;
+ }
+ return (FALSE); /* Didn't process a message */
+}
+
+
+HDDEDATA CALLBACK DdeCallback(
+ UINT wType,
+ UINT wFmt,
+ HCONV hConv,
+ HSZ hsz1,
+ HSZ hsz2,
+ HDDEDATA hData,
+ UINT dwData1,
+ UINT dwData2)
+{
+ LPVOID pData;
+ UINT cb;
+ TCHAR *psz1, *psz2, *psz3;
+ TCHAR *szAction;
+ INT i;
+ BOOL fInt = FALSE;
+ wFmt;
+ hConv;
+ dwData1;
+
+ switch (wType) {
+ case XTYP_MONITOR:
+ if (pData = DdeAccessData(hData, (LPDWORD)&cb)) {
+ switch (dwData2) {
+ case MF_HSZ_INFO:
+ if (pro.fTrack[IT_HSZS]) {
+ switch (((MONHSZSTRUCT FAR *)pData)->fsAction) {
+ case MH_DELETE:
+ wsprintf(TBuf, fInt ? TEXT("0x%lx\t*\t%s(int)")
+ : TEXT("0x%lx\t*\t%s"),
+ ((MONHSZSTRUCT FAR *)pData)->hsz,
+ (LPTSTR)((MONHSZSTRUCT FAR *)pData)->str);
+ i = GetMCLBColValue(TBuf, hwndTrack[IT_HSZS], 2);
+ if (i > 1) {
+ wsprintf(TBuf2, fInt ? TEXT("0x%lx\t%d\t%s(int)")
+ : TEXT("0x%lx\t%d\t%s"),
+ ((MONHSZSTRUCT FAR *)pData)->hsz,
+ i - 1,
+ (LPTSTR)((MONHSZSTRUCT FAR *)pData)->str);
+ AddMCLBText(TBuf, TBuf2, hwndTrack[IT_HSZS]);
+ } else if (i == 1) {
+ DeleteMCLBText(TBuf, hwndTrack[IT_HSZS]);
+ }
+ break;
+
+ case MH_KEEP:
+ case MH_CREATE:
+ wsprintf(TBuf, fInt ? TEXT("0x%lx\t*\t%s(int)")
+ : TEXT("0x%lx\t*\t%s"),
+ ((MONHSZSTRUCT FAR *)pData)->hsz,
+ (LPTSTR)((MONHSZSTRUCT FAR *)pData)->str);
+ i = GetMCLBColValue(TBuf, hwndTrack[IT_HSZS], 2) + 1;
+ wsprintf(TBuf2, fInt ? TEXT("0x%lx\t%d\t%s(int)")
+ : TEXT("0x%lx\t%d\t%s"),
+ ((MONHSZSTRUCT FAR *)pData)->hsz,
+ i,
+ (LPTSTR)((MONHSZSTRUCT FAR *)pData)->str);
+ AddMCLBText(TBuf, TBuf2, hwndTrack[IT_HSZS]);
+ }
+ }
+
+ if (!pro.fFilter[IF_HSZ]) {
+ DdeUnaccessData(hData);
+ return(0);
+ }
+
+ switch (((MONHSZSTRUCT FAR *)pData)->fsAction) {
+ case MH_CLEANUP:
+ szAction = RefString(IDS_ACTION_CLEANEDUP);
+ break;
+
+ case MH_DELETE:
+ szAction = RefString(IDS_ACTION_DESTROYED);
+ break;
+
+ case MH_KEEP:
+ szAction = RefString(IDS_ACTION_INCREMENTED);
+ break;
+
+ case MH_CREATE:
+ szAction = RefString(IDS_ACTION_CREATED);
+ break;
+
+ default:
+ DdeUnaccessData(hData);
+ return(0);
+ }
+ if (pro.fTerse) {
+ wsprintf(TBuf, TEXT("[%x:%ld] HSZ %s: %lx(%s)"),
+ ((MONHSZSTRUCT FAR *)pData)->hTask,
+ ((MONHSZSTRUCT FAR *)pData)->dwTime,
+ (LPTSTR)szAction,
+ ((MONHSZSTRUCT FAR *)pData)->hsz,
+ (LPTSTR)((MONHSZSTRUCT FAR *)pData)->str);
+ } else {
+ wsprintf(TBuf,
+ /* so we can localize message */
+ RefString(IDS_FMT_SH_MSG1),
+ ((MONHSZSTRUCT FAR *)pData)->hTask,
+ ((MONHSZSTRUCT FAR *)pData)->dwTime,
+ (LPTSTR)szAction,
+ ((MONHSZSTRUCT FAR *)pData)->hsz,
+ (LPTSTR)((MONHSZSTRUCT FAR *)pData)->str);
+ }
+ break;
+
+
+ case MF_SENDMSGS:
+ case MF_POSTMSGS:
+ if (fBlockMsg[((MONMSGSTRUCT FAR *)pData)->wMsg - WM_DDE_FIRST]) {
+ DdeUnaccessData(hData);
+ return(0);
+ }
+ if (pro.fTerse) {
+ wsprintf(TBuf, RefString(IDS_FMT_TRS_MSG1),
+ ((MONMSGSTRUCT FAR *)pData)->hTask,
+ ((MONMSGSTRUCT FAR *)pData)->dwTime,
+ ((MONMSGSTRUCT FAR *)pData)->wParam,
+ ((MONMSGSTRUCT FAR *)pData)->hwndTo,
+ (dwData2 == MF_SENDMSGS) ? RefString(IDS_SENT) : RefString(IDS_POSTED),
+ (LPTSTR)DdeMsg2String(((MONMSGSTRUCT FAR *)pData)->wMsg));
+ } else {
+ wsprintf(TBuf, RefString(IDS_FMT_MSG1),
+ ((MONMSGSTRUCT FAR *)pData)->hTask,
+ ((MONMSGSTRUCT FAR *)pData)->dwTime,
+ ((MONMSGSTRUCT FAR *)pData)->hwndTo,
+ (dwData2 == MF_SENDMSGS) ? RefString(IDS_SENT) : RefString(IDS_POSTED),
+ (LPTSTR)DdeMsg2String(((MONMSGSTRUCT FAR *)pData)->wMsg));
+ }
+ OutputString(TBuf);
+ wsprintf(TBuf, pro.fTerse ? RefString(IDS_FMT_TRS_MSG2) : RefString(IDS_FMT_MSG2),
+ ((MONMSGSTRUCT FAR *)pData)->wParam);
+ DisectMsgLP(((MONMSGSTRUCT FAR *)pData)->wMsg,
+ ((MONMSGSTRUCT FAR *)pData),
+ &TBuf[lstrlen(TBuf)]);
+ break;
+
+
+ case MF_CALLBACKS:
+ if (fBlockCb[(((MONCBSTRUCT FAR *)pData)->wType & XTYP_MASK) >> XTYP_SHIFT]) {
+ DdeUnaccessData(hData);
+ return(0);
+ }
+ wsprintf(TBuf,
+ pro.fTerse ? RefString(IDS_FMT_TRS_CB1) : RefString(IDS_FMT_CB1),
+ ((MONCBSTRUCT FAR *)pData)->hTask,
+ ((MONCBSTRUCT FAR *)pData)->dwTime,
+ (LPTSTR)Type2String(((MONCBSTRUCT FAR *)pData)->wType));
+ wsprintf(DumpFormat(((MONCBSTRUCT FAR *)pData)->wFmt, &TBuf[lstrlen(TBuf)]),
+ pro.fTerse ? RefString(IDS_FMT_TRS_CB2) : RefString(IDS_FMT_CB2),
+ (UINT)((MONCBSTRUCT FAR *)pData)->hConv,
+ ((MONCBSTRUCT FAR *)pData)->hsz1,
+ (LPTSTR)(psz1 = GetHszName(((MONCBSTRUCT FAR *)pData)->hsz1)),
+ ((MONCBSTRUCT FAR *)pData)->hsz2,
+ (LPTSTR)(psz2 = GetHszName(((MONCBSTRUCT FAR *)pData)->hsz2)),
+ ((MONCBSTRUCT FAR *)pData)->hData,
+ ((MONCBSTRUCT FAR *)pData)->dwData1,
+ ((MONCBSTRUCT FAR *)pData)->dwData2,
+ ((MONCBSTRUCT FAR *)pData)->dwRet);
+ MyFree(psz1);
+ MyFree(psz2);
+ OutputString(TBuf);
+ if (((MONCBSTRUCT FAR *)pData)->dwData1 &&
+ (((MONCBSTRUCT FAR *)pData)->wType == XTYP_CONNECT ||
+ ((MONCBSTRUCT FAR *)pData)->wType == XTYP_WILDCONNECT)) {
+ // display proposed context
+ wsprintf(TBuf,
+ pro.fTerse ? RefString(IDS_FMT_TRS_CTXT1) : RefString(IDS_FMT_CTXT1),
+ ((MONCBSTRUCT FAR *)pData)->cc.wFlags,
+ ((MONCBSTRUCT FAR *)pData)->cc.wCountryID,
+ ((MONCBSTRUCT FAR *)pData)->cc.iCodePage,
+ ((MONCBSTRUCT FAR *)pData)->cc.dwLangID,
+ ((MONCBSTRUCT FAR *)pData)->cc.dwSecurity,
+ ((MONCBSTRUCT FAR *)pData)->cc.qos.ImpersonationLevel,
+ ((MONCBSTRUCT FAR *)pData)->cc.qos.ContextTrackingMode,
+ ((MONCBSTRUCT FAR *)pData)->cc.qos.EffectiveOnly);
+ OutputString(TBuf);
+ }
+ if (((MONCBSTRUCT FAR *)pData)->hData && ((MONCBSTRUCT FAR *)pData)->cbData) {
+ wsprintf(TBuf, RefString(IDS_INPUT_DATA));
+ OutputString(TBuf);
+ DumpData((LPBYTE)((MONCBSTRUCT FAR *)pData)->Data,
+ ((MONCBSTRUCT FAR *)pData)->cbData,
+ TBuf,
+ ((MONCBSTRUCT FAR *)pData)->wFmt);
+ OutputString(TBuf);
+ if (cb > MAX_DISPDATA)
+ OutputString(RefString(IDS_TABDDD));
+ // DdeUnaccessData(((MONCBSTRUCT FAR *)pData)->hData);
+ }
+ if ((((MONCBSTRUCT FAR *)pData)->wType & XCLASS_DATA) &&
+ ((MONCBSTRUCT FAR *)pData)->dwRet &&
+ ((MONCBSTRUCT FAR *)pData)->cbData) {
+ wsprintf(TBuf, RefString(IDS_OUTPUT_DATA));
+ OutputString(TBuf);
+ DumpData((LPBYTE)((MONCBSTRUCT FAR *)pData)->Data,
+ ((MONCBSTRUCT FAR *)pData)->cbData,
+ TBuf,
+ ((MONCBSTRUCT FAR *)pData)->wFmt);
+ OutputString(TBuf);
+ if (cb > MAX_DISPDATA)
+ OutputString(RefString(IDS_TABDDD));
+ // DdeUnaccessData(((MONCBSTRUCT FAR *)pData)->dwRet);
+ }
+ DdeUnaccessData(hData);
+ return(0);
+ break;
+
+ case MF_ERRORS:
+ wsprintf(TBuf, pro.fTerse ? RefString(IDS_FMT_TRS_ER1) : RefString(IDS_FMT_ER1),
+ ((MONERRSTRUCT FAR *)pData)->hTask,
+ ((MONERRSTRUCT FAR *)pData)->dwTime,
+ ((MONERRSTRUCT FAR *)pData)->wLastError,
+ (LPTSTR)Error2String(((MONERRSTRUCT FAR *)pData)->wLastError));
+ break;
+
+
+ case MF_LINKS:
+ psz1 = GetHszName(((MONLINKSTRUCT FAR *)pData)->hszSvc);
+ psz2 = GetHszName(((MONLINKSTRUCT FAR *)pData)->hszTopic);
+ psz3 = GetHszName(((MONLINKSTRUCT FAR *)pData)->hszItem);
+ if (!GetClipboardFormatName(((MONLINKSTRUCT FAR *)pData)->wFmt, TBuf2, BUFFER_SIZE))
+ lstrcpy(TBuf2, pdf(((MONLINKSTRUCT FAR *)pData)->wFmt));
+ if (!lstrcmp(RefString(IDS_HUH), TBuf2)) {
+ wsprintf(TBuf2, TEXT("%d"), ((MONLINKSTRUCT FAR *)pData)->wFmt);
+ }
+
+ wsprintf(TBuf, TEXT("%s\t%s\t%s\t%s\t%s\t%lx\t%lx"),
+ (LPTSTR)psz1, (LPTSTR)psz2, (LPTSTR)psz3,
+ (LPTSTR)TBuf2,
+ ((MONLINKSTRUCT FAR *)pData)->fNoData ?
+ RefString(IDS_WARM) : RefString(IDS_HOT),
+ ((MONLINKSTRUCT FAR *)pData)->hConvClient,
+ ((MONLINKSTRUCT FAR *)pData)->hConvServer);
+
+ if (((MONLINKSTRUCT FAR *)pData)->fEstablished) {
+ AddMCLBText(TBuf, TBuf, hwndTrack[IT_LINKS]);
+ } else {
+ DeleteMCLBText(TBuf, hwndTrack[IT_LINKS]);
+ }
+
+ MyFree(psz1);
+ MyFree(psz2);
+ MyFree(psz3);
+ DdeUnaccessData(hData);
+ return(0);
+
+
+ case MF_CONV:
+ psz1 = GetHszName(((MONCONVSTRUCT FAR *)pData)->hszSvc);
+ psz2 = GetHszName(((MONCONVSTRUCT FAR *)pData)->hszTopic);
+
+ wsprintf(TBuf, TEXT("%s\t%s\t%lx\t%lx"),
+ (LPTSTR)psz1, (LPTSTR)psz2,
+ ((MONCONVSTRUCT FAR *)pData)->hConvClient,
+ ((MONCONVSTRUCT FAR *)pData)->hConvServer);
+
+ if (((MONCONVSTRUCT FAR *)pData)->fConnect) {
+ AddMCLBText(TBuf, TBuf, hwndTrack[IT_CONVS]);
+ } else {
+ DeleteMCLBText(TBuf, hwndTrack[IT_CONVS]);
+ }
+
+ MyFree(psz1);
+ MyFree(psz2);
+ DdeUnaccessData(hData);
+ return(0);
+
+
+ default:
+ lstrcpy(TBuf, RefString(IDS_UNKNOWN_CALLBACK));
+ }
+ DdeUnaccessData(hData);
+ OutputString(TBuf);
+ }
+ break;
+
+ case XTYP_REGISTER:
+ case XTYP_UNREGISTER:
+ if (!pro.fTrack[IT_SVRS]) {
+ return(0);
+ }
+ psz1 = GetHszName(hsz1);
+ psz2 = GetHszName(hsz2);
+ wsprintf(TBuf, TEXT("%s\t%s"), (LPTSTR)psz1, (LPTSTR)psz2);
+ if (wType == XTYP_REGISTER) {
+ AddMCLBText(NULL, TBuf, hwndTrack[IT_SVRS]);
+ } else {
+ DeleteMCLBText(TBuf, hwndTrack[IT_SVRS]);
+ }
+ MyFree(psz1);
+ MyFree(psz2);
+ break;
+ }
+ return(0);
+}
+
+
+LPTSTR DisectMsgLP(UINT msg, MONMSGSTRUCT *pmms, LPTSTR pszBuf)
+{
+ static LONG m2t[] = {
+
+ /* LOW HIGH */
+
+ MAKELONG(T_APP | T_ATOM, T_TOPIC | T_ATOM), // WM_DDE_INITIATE
+ 0, // WM_DDE_TERMINATE
+ MAKELONG(T_OPTIONHANDLE, T_ITEM | T_ATOM), // WM_DDE_ADVISE
+ MAKELONG(T_FORMAT, T_ITEM | T_ATOM), // WM_DDE_UNADVISE
+ MAKELONG(T_APP | T_ATOM | T_OR | T_STATUS,
+ T_TOPIC | T_ITEM | T_ATOM | T_OR | T_STRINGHANDLE),
+ // WM_DDE_ACK
+ MAKELONG(T_DATAHANDLE, T_ITEM | T_ATOM), // WM_DDE_DATA
+ MAKELONG(T_FORMAT, T_ITEM | T_ATOM), // WM_DDE_REQUEST
+ MAKELONG(T_DATAHANDLE, T_ITEM | T_ATOM), // WM_DDE_POKE
+ MAKELONG(0, T_STRINGHANDLE), // WM_DDE_EXECUTE
+ };
+
+ // ASSUMED: msg is a valid DDE message!!!
+
+ pszBuf = DisectWord(LOWORD(m2t[msg - WM_DDE_FIRST]),
+ pmms->dmhd.uiLo, &pmms->dmhd, pszBuf);
+ *pszBuf++ = TEXT('\r');
+ *pszBuf++ = TEXT('\n');
+ *pszBuf++ = TEXT('\t');
+ return(DisectWord(HIWORD(m2t[msg - WM_DDE_FIRST]),
+ pmms->dmhd.uiHi, &pmms->dmhd, pszBuf));
+}
+
+
+
+
+/*
+ * Allocates local memory for and retrieves the string form of an HSZ.
+ * Returns a pointer to the local memory or NULL if failure.
+ * The string must be freed via MyFree().
+ */
+LPTSTR GetHszName(HSZ hsz)
+{
+ LPTSTR psz;
+ UINT cb;
+
+ cb = (UINT)DdeQueryString(idInst, hsz, NULL, 0, 0) + 1;
+ psz = LocalAlloc (LPTR, sizeof(TCHAR) * cb);
+ DdeQueryString(idInst, hsz, psz, cb, 0);
+ return(psz);
+}
+
+
+
+
+LPTSTR DisectWord( UINT type,
+UINT data,
+DDEML_MSG_HOOK_DATA *pdmhd,
+LPTSTR pstr)
+{
+ UINT wT;
+
+ *pstr = TEXT('\0'); // in case we do nothing.
+
+ if (type & T_ATOM) {
+ wT = GlobalGetAtomName((ATOM)data, (LPTSTR)pstr, 25);
+ if (wT || data == 0) {
+ if (type & T_APP) {
+ lstrcpy(pstr, RefString(IDS_APPIS));
+ pstr += lstrlen(pstr);
+ }
+
+ if (type & T_TOPIC) {
+ lstrcpy(pstr, RefString(IDS_TOPICIS));
+ pstr += lstrlen(pstr);
+ }
+
+ if (type & T_ITEM) {
+ lstrcpy(pstr, RefString(IDS_ITEMIS));
+ pstr += lstrlen(pstr);
+ }
+ }
+ if (wT) {
+ wsprintf(pstr, TEXT("0x%x(\""), data);
+ pstr += lstrlen(pstr);
+ GlobalGetAtomName((ATOM)data, (LPTSTR)pstr, 25);
+ pstr += wT;
+ if (wT == 25) {
+ *pstr++ = TEXT('.');
+ *pstr++ = TEXT('.');
+ *pstr++ = TEXT('.');
+ }
+ *pstr++ = TEXT('\"');
+ *pstr++ = TEXT(')');
+ *pstr = TEXT('\0');
+ type &= ~(T_OR | T_STRINGHANDLE); // its an atom, so its not an object!
+ } else if (data == 0) { // could be a wild atom
+ *pstr++ = TEXT('*');
+ *pstr = TEXT('\0');
+ } else if (type & T_OR) {
+ type &= ~T_OR; // not an atom, must be somthin else.
+ } else {
+ /* so we can localize message */
+ wsprintf(pstr, RefString(IDS_BADATOM), data);
+ pstr += lstrlen(pstr);
+ }
+ }
+
+ if (type & T_OR) {
+ lstrcpy(pstr, RefString(IDS_OR));
+ pstr += lstrlen(pstr);
+ }
+
+
+ if (type & T_OPTIONHANDLE) {
+ if (pdmhd->cbData >= 4) {
+ wsprintf(pstr, pro.fTerse ? RefString(IDS_FMT_TRS_STATUSIS) : RefString(IDS_FMT_STATUSIS), LOWORD(pdmhd->Data[0]));
+ pstr += lstrlen(pstr);
+ if (LOWORD(pdmhd->Data[0]) & DDE_FACKREQ) {
+ lstrcpy(pstr, RefString(IDS_FACKREQ));
+ pstr += lstrlen(pstr);
+ }
+ if (LOWORD(pdmhd->Data[0]) & DDE_FDEFERUPD) {
+ lstrcpy(pstr, RefString(IDS_DEFERUPD));
+ pstr += lstrlen(pstr);
+ }
+ *pstr++ = TEXT(')');
+ *pstr++ = TEXT(' ');
+ pstr = DumpFormat((UINT)HIWORD(pdmhd->Data[0]), pstr);
+ }
+ }
+
+ if (type & T_FORMAT) {
+ pstr = DumpFormat(data, pstr);
+ }
+
+ if (type & T_STATUS) {
+ wsprintf(pstr, pro.fTerse ? RefString(IDS_FMT_TRS_STATUSIS) : RefString(IDS_FMT_STATUSIS), LOWORD(data));
+ pstr += lstrlen(pstr);
+ if (data & DDE_FACK) {
+ lstrcpy(pstr, RefString(IDS_FACK));
+ pstr += lstrlen(pstr);
+ }
+ if (data & DDE_FBUSY) {
+ lstrcpy(pstr, RefString(IDS_FBUSY));
+ pstr += lstrlen(pstr);
+ }
+ *pstr++ = TEXT(')');
+ *pstr = TEXT('\0');
+ }
+
+ if (type & T_STRINGHANDLE && pdmhd->cbData) {
+ WCHAR szData[16];
+
+ memset(szData, '\0', 16 * sizeof(WCHAR));
+ memcpy(szData, pdmhd->Data, min(16 * sizeof(WCHAR), pdmhd->cbData));
+ szData[15] = L'\0';
+ wsprintf(pstr, pro.fTerse ?
+ RefString(IDS_FMT_TRS_EXEC1) : RefString(IDS_FMT_EXEC1), (LPWSTR)szData);
+ pstr += lstrlen(pstr);
+ *pstr = TEXT('\0');
+ }
+
+ if (type & T_DATAHANDLE && pdmhd->cbData) {
+ wsprintf(pstr, pro.fTerse ?
+ RefString(IDS_FMT_TRS_STATUSIS) : RefString(IDS_FMT_STATUSIS),
+ LOWORD(pdmhd->Data[0]));
+ pstr += lstrlen(pstr);
+ if (LOWORD(pdmhd->Data[0]) & DDE_FRELEASE) {
+ lstrcpy(pstr, RefString(IDS_FRELEASE));
+ pstr += lstrlen(pstr);
+ }
+ if (LOWORD(pdmhd->Data[0]) & DDE_FREQUESTED) {
+ lstrcpy(pstr, RefString(IDS_FREQUESTED));
+ pstr += lstrlen(pstr);
+ }
+ *pstr++ = TEXT(')');
+ *pstr++ = TEXT(' ');
+ pstr = DumpFormat(HIWORD(pdmhd->Data[0]), pstr);
+ lstrcpy(pstr, pro.fTerse ? RefString(IDS_FMT_TRS_DATAIS1) : RefString(IDS_FMT_DATAIS1));
+ pstr += lstrlen(pstr);
+ pstr = DumpData((LPBYTE)&pdmhd->Data[1], min(28, pdmhd->cbData - 4),
+ pstr, HIWORD(pdmhd->Data[0]));
+ }
+ return(pstr);
+}
+
+
+LPTSTR pdf(UINT fmt)
+{
+ INT i;
+ static struct {
+ UINT fmt;
+ LPTSTR psz;
+ } fmts[] = {
+ { CF_TEXT , TEXT("CF_TEXT") } ,
+ { CF_UNICODETEXT , TEXT("CF_UNICODETEXT") } ,
+ { CF_BITMAP , TEXT("CF_BITMAP") } ,
+ { CF_METAFILEPICT , TEXT("CF_METAFILEPICT") } ,
+ { CF_ENHMETAFILE , TEXT("CF_ENHMETAFILE") } ,
+ { CF_SYLK , TEXT("CF_SYLK") } ,
+ { CF_DIF , TEXT("CF_DIF") } ,
+ { CF_TIFF , TEXT("CF_TIFF") } ,
+ { CF_OEMTEXT , TEXT("CF_OEMTEXT") } ,
+ { CF_DIB , TEXT("CF_DIB") } ,
+ { CF_PALETTE , TEXT("CF_PALETTE") } ,
+ };
+ for (i = 0; i < 10; i++)
+ if (fmts[i].fmt == fmt)
+ return(fmts[i].psz);
+ return(RefString(IDS_HUH));
+}
+
+
+
+LPTSTR DumpFormat(UINT fmt, LPTSTR pstr)
+{
+ UINT cb;
+
+ wsprintf(pstr, TEXT("fmt=0x%x(\""), (WORD)fmt);
+ pstr += lstrlen(pstr);
+ if (cb = GetClipboardFormatName(fmt, pstr, 25)) {
+ pstr += cb;
+ *pstr++ = TEXT('\"');
+ *pstr++ = TEXT(')');
+ } else {
+ wsprintf(pstr, TEXT("%s\")"), (LPTSTR)pdf(fmt));
+ pstr += lstrlen(pstr);
+ }
+ return(pstr);
+}
+
+
+
+LPTSTR DumpData(LPBYTE pData, UINT cb, TCHAR *szBuf, UINT fmt)
+{
+ register INT i;
+ LPTSTR psz = szBuf;
+
+
+ while (cb) {
+ if (fmt == CF_TEXT || fmt == CF_UNICODETEXT) {
+ *szBuf++ = TEXT('\t');
+ if (fmt == CF_UNICODETEXT) {
+ *szBuf++ = TEXT('U');
+ }
+ *szBuf++ = TEXT('\"');
+ if (fmt == CF_UNICODETEXT) {
+ memcpy(szBuf, pData, cb);
+ } else {
+ MultiByteToWideChar(CP_ACP, 0, pData, cb, szBuf, cb / sizeof(TCHAR));
+ }
+ szBuf[cb - 2] = TEXT('\0');
+ lstrcat(szBuf, TEXT("\""));
+ cb = 0;
+ } else {
+ for (i = 0; i < 80 ; i++) {
+ szBuf[i] = TEXT(' ');
+ }
+ szBuf[0] = TEXT('\t');
+ i = 0;
+ while (cb && (i < 16)) {
+ wsprintf(&szBuf[i * 3 + 1], TEXT("%02x "), pData[0]);
+ wsprintf(&szBuf[17 * 3 + i + 1], TEXT("%c"), MPRT(pData[0]));
+ pData++;
+ cb--;
+ i++;
+ }
+ szBuf[i * 3 + 1] = TEXT(' ');
+ szBuf[17 * 3 + i + 1] = TEXT(' ');
+ szBuf[68] = TEXT('\0');
+ }
+ szBuf += lstrlen(szBuf);
+ }
+ return(szBuf);
+}
+
+
+
+LPTSTR Error2String(UINT error)
+{
+ static TCHAR szErr[23];
+
+ if (error == 0) {
+ lstrcpy(szErr, RefString(IDS_ZERO));
+ } else if (error > DMLERR_LAST || error < DMLERR_FIRST) {
+ lstrcpy(szErr, RefString(IDS_HUH));
+ } else {
+ lstrcpy(szErr, apszResources[IDS_ERRST0 + error - DMLERR_FIRST]);
+ }
+ return(szErr);
+}
+
+
+
+LPTSTR DdeMsg2String(UINT msg)
+{
+ static TCHAR szBadMsg[10];
+
+ if (msg < WM_DDE_FIRST || msg > WM_DDE_LAST) {
+ wsprintf (szBadMsg, TEXT("%ld"), szBadMsg);
+ return (szBadMsg);
+// return((LPTSTR)itoa(msg, szBadMsg, 10));
+ } else {
+ return(apszResources[IDS_MSG0 + msg - WM_DDE_FIRST]);
+ }
+}
+
+
+
+VOID OutputString(LPTSTR pstr)
+{
+ DWORD cbWritten;
+
+ if (pro.fOutput[IO_FILE] && fhOutput != NULL) {
+ static CHAR szT[200];
+
+ WideCharToMultiByte(
+ CP_ACP,
+ 0,
+ pstr,
+ -1,
+ szT,
+ 200,
+ NULL,
+ NULL);
+ WriteFile(fhOutput, (LPCSTR) szT, lstrlenA(szT), &cbWritten, NULL);
+ WriteFile(fhOutput, (LPCSTR) "\r\n", 2, &cbWritten, NULL);
+ FlushFileBuffers(fhOutput);
+ }
+ if (pro.fOutput[IO_DEBUG]) {
+ OutputDebugString((LPTSTR)pstr);
+ OutputDebugString(RefString(IDS_CRLF));
+ }
+ if (pro.fOutput[IO_SCREEN]) {
+ if (IsWindow(hWndString))
+ DrawString(hWndString, pstr);
+ }
+}
+
+
+
+BOOL SetFilters()
+{
+ UINT cbf;
+
+ cbf = 0;
+ if (pro.fTrack[IT_HSZS] || pro.fFilter[IF_HSZ])
+ cbf |= MF_HSZ_INFO;
+ if (pro.fTrack[IT_LINKS])
+ cbf |= MF_LINKS;
+ if (pro.fTrack[IT_CONVS])
+ cbf |= MF_CONV;
+ if (pro.fFilter[IF_SEND])
+ cbf |= MF_SENDMSGS;
+ if (pro.fFilter[IF_POST])
+ cbf |= MF_POSTMSGS;
+ if (pro.fFilter[IF_CB])
+ cbf |= MF_CALLBACKS;
+ if (pro.fFilter[IF_ERR])
+ cbf |= MF_ERRORS;
+ return((BOOL)DdeInitialize(&idInst, pfnDdeCallback, APPCLASS_MONITOR | cbf, 0));
+}
+
+
+
+
+
+/*
+ * This dialog returns a file handle to the opened file name given or NULL
+ * if cancel.
+ */
+
+BOOL CALLBACK OpenDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ HANDLE fh;
+ lParam;
+
+ switch (message) {
+ case WM_INITDIALOG:
+ SetDlgItemText(hDlg, IDC_EDIT, (LPTSTR)OpenName);
+ SendDlgItemMessage(hDlg, IDC_EDIT, EM_SETSEL,
+ GET_EM_SETSEL_MPS(0, 0x7fff));
+ SetFocus(GetDlgItem(hDlg, IDC_EDIT));
+ return (FALSE); /* Indicates the focus is set to a control */
+ break;
+
+ case WM_COMMAND:
+ switch (GET_WM_COMMAND_ID(wParam, lParam)) {
+ case IDOK:
+ GetDlgItemText(hDlg, IDC_EDIT, TBuf, MAX_FNAME);
+ GetFullPathName(TBuf, sizeof(OpenName), OpenName, (LPTSTR *)TBuf2);
+ fh = CreateFile(
+ OpenName,
+ GENERIC_WRITE,
+ FILE_SHARE_READ,
+ (PSECURITY_ATTRIBUTES)NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (fh == INVALID_HANDLE_VALUE) {
+ MessageBox(hDlg, RefString(IDS_INVALID_FNAME),
+ NULL, MB_OK | MB_ICONHAND);
+ return (TRUE);
+ }
+
+ EndDialog(hDlg, (INT)fh);
+ return (TRUE);
+
+ case IDCANCEL:
+ EndDialog(hDlg, 0);
+ return (FALSE);
+ }
+ break;
+ }
+ return FALSE;
+}
+
+BOOL CALLBACK FilterDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ int i;
+ lParam;
+
+ switch (message) {
+ case WM_INITDIALOG:
+ for (i = IDRB_WM_DDE_INITIATE; i <= IDRB_WM_DDE_EXECUTE; i++) {
+ CheckDlgButton(hDlg, i, !fBlockMsg[i - IDRB_WM_DDE_INITIATE]);
+ }
+ for (i = IDRB_XTYP_ERROR; i <= IDRB_XTYP_WILDCONNECT; i++) {
+ CheckDlgButton(hDlg, i, !fBlockCb[i - IDRB_XTYP_ERROR]);
+ }
+ CheckDlgButton(hDlg, IDRB_TERSE, pro.fTerse);
+ return TRUE;
+ break;
+
+ case WM_COMMAND:
+ switch (GET_WM_COMMAND_ID(wParam, lParam)) {
+ case IDOK:
+ for (i = IDRB_WM_DDE_INITIATE; i <= IDRB_WM_DDE_EXECUTE; i++) {
+ fBlockMsg[i - IDRB_WM_DDE_INITIATE] = !IsDlgButtonChecked(hDlg, i);
+ }
+ for (i = IDRB_XTYP_ERROR; i <= IDRB_XTYP_WILDCONNECT; i++) {
+ fBlockCb[i - IDRB_XTYP_ERROR] = !IsDlgButtonChecked(hDlg, i);
+ }
+ pro.fTerse = IsDlgButtonChecked(hDlg, IDRB_TERSE);
+ EndDialog(hDlg, TRUE);
+ break;
+
+ case IDCANCEL:
+ EndDialog(hDlg, 0);
+ break;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+
+
+
+VOID GetProfile()
+{
+ pro.fOutput[IO_FILE] = GetProfileBoolean(RefString(IDS_PROF_OUT_FILE),FALSE);
+ pro.fOutput[IO_DEBUG] = GetProfileBoolean(RefString(IDS_PROF_OUT_DEBUG),FALSE);
+ pro.fOutput[IO_SCREEN] = GetProfileBoolean(RefString(IDS_PROF_OUT_SCREEN),FALSE);
+
+ pro.fFilter[IF_HSZ] = GetProfileBoolean(RefString(IDS_PROF_MONITOR_STRINGHANDLES),FALSE);
+ pro.fFilter[IF_SEND] = GetProfileBoolean(RefString(IDS_PROF_MONITOR_INITIATES), FALSE);
+ pro.fFilter[IF_POST] = GetProfileBoolean(RefString(IDS_PROF_MONITOR_DDE_MESSAGES), FALSE);
+ pro.fFilter[IF_CB] = GetProfileBoolean(RefString(IDS_PROF_MONITOR_CALLBACKS), FALSE);
+ pro.fFilter[IF_ERR] = GetProfileBoolean(RefString(IDS_PROF_MONITOR_ERRORS),FALSE);
+
+ pro.fTrack[IT_HSZS] = GetProfileBoolean(RefString(IDS_PROF_TRACK_STRINGHANDLES), FALSE);
+ pro.fTrack[IT_LINKS] = GetProfileBoolean(RefString(IDS_PROF_TRACK_LINKS), FALSE);
+ pro.fTrack[IT_CONVS] = GetProfileBoolean(RefString(IDS_PROF_TRACK_CONVERSATIONS), FALSE);
+ pro.fTrack[IT_SVRS] = GetProfileBoolean(RefString(IDS_PROF_TRACK_SERVICES), FALSE);
+
+ pro.fTerse = GetProfileBoolean(RefString(IDS_PROF_TERSE), FALSE);
+}
+
+
+
+VOID SaveProfile()
+{
+ SetProfileBoolean(RefString(IDS_PROF_OUT_FILE), pro.fOutput[IO_FILE] );
+ SetProfileBoolean(RefString(IDS_PROF_OUT_DEBUG), pro.fOutput[IO_DEBUG] );
+ SetProfileBoolean(RefString(IDS_PROF_OUT_SCREEN), pro.fOutput[IO_SCREEN]);
+
+ SetProfileBoolean(RefString(IDS_PROF_MONITOR_STRINGHANDLES), pro.fFilter[IF_HSZ] );
+ SetProfileBoolean(RefString(IDS_PROF_MONITOR_INITIATES), pro.fFilter[IF_SEND] );
+ SetProfileBoolean(RefString(IDS_PROF_MONITOR_DDE_MESSAGES), pro.fFilter[IF_POST] );
+ SetProfileBoolean(RefString(IDS_PROF_MONITOR_CALLBACKS), pro.fFilter[IF_CB] );
+ SetProfileBoolean(RefString(IDS_PROF_MONITOR_ERRORS), pro.fFilter[IF_ERR] );
+
+ SetProfileBoolean(RefString(IDS_PROF_TRACK_STRINGHANDLES), pro.fTrack[IT_HSZS] );
+ SetProfileBoolean(RefString(IDS_PROF_TRACK_LINKS), pro.fTrack[IT_LINKS] );
+ SetProfileBoolean(RefString(IDS_PROF_TRACK_CONVERSATIONS), pro.fTrack[IT_CONVS] );
+ SetProfileBoolean(RefString(IDS_PROF_TRACK_SERVICES), pro.fTrack[IT_SVRS] );
+
+ SetProfileBoolean(RefString(IDS_PROF_TERSE), pro.fTerse );
+}
+
+
+
+
+BOOL GetProfileBoolean(LPTSTR pszKey, BOOL fDefault)
+{
+ GetPrivateProfileString(RefString(IDS_TITLE), pszKey,
+ fDefault ? RefString(IDS_YES) : RefString(IDS_NO), TBuf,
+ sizeof(TBuf), RefString(IDS_INIFNAME));
+ return(lstrcmpi(RefString(IDS_NO), TBuf));
+}
+
+
+
+VOID SetProfileBoolean(LPTSTR pszKey, BOOL fSet)
+{
+ WritePrivateProfileString(RefString(IDS_TITLE), pszKey,
+ fSet ? RefString(IDS_YES) : RefString(IDS_NO),
+ RefString(IDS_INIFNAME));
+}
+
+/*
+ * Generic dialog invocation routine. Handles procInstance stuff and param
+ * passing.
+ */
+INT FAR DoDialog(
+ LPTSTR lpTemplateName,
+ DLGPROC lpDlgProc,
+ UINT param,
+ BOOL fRememberFocus,
+ HWND hwndParent,
+ HANDLE hInst)
+{
+ UINT wRet;
+ HWND hwndFocus;
+
+ if (fRememberFocus)
+ hwndFocus = GetFocus();
+ lpDlgProc = (DLGPROC)MakeProcInstance(lpDlgProc, hInst);
+ wRet = DialogBoxParam(hInst, (LPCTSTR)lpTemplateName, hwndParent,
+ lpDlgProc, param);
+ FreeProcInstance((FARPROC)lpDlgProc);
+ if (fRememberFocus)
+ SetFocus(hwndFocus);
+ return wRet;
+}
+
+
+BOOL CALLBACK MarkDlgProc(
+ HWND hwnd,
+ UINT msg,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ TCHAR szT[MAX_MARK + 1];
+ lParam;
+
+ switch (msg){
+ case WM_INITDIALOG:
+ SetWindowText(hwnd, RefString(IDS_MARKDLGTITLE));
+ SendDlgItemMessage(hwnd, IDEF_VALUE, EM_LIMITTEXT, MAX_MARK, 0);
+ SetDlgItemText(hwnd, IDEF_VALUE, RefString(IDS_SEPERATOR));
+ SetDlgItemText(hwnd, IDTX_VALUE, RefString(IDS_MARKTEXT));
+ return(1);
+ break;
+
+ case WM_COMMAND:
+ switch (GET_WM_COMMAND_ID(wParam, lParam)) {
+ case IDOK:
+ GetDlgItemText(hwnd, IDEF_VALUE, szT, MAX_MARK);
+ OutputString(szT);
+ // fall through
+ case IDCANCEL:
+ EndDialog(hwnd, 0);
+ break;
+
+ default:
+ return(FALSE);
+ }
+ break;
+ }
+ return(FALSE);
+}
+
+
+#ifdef DBCS
+/****************************************************************************
+ My_mbschr: strchr() DBCS version
+****************************************************************************/
+LPTSTR _CRTAPI1 My_mbschr(
+ LPTSTR psz, TCHAR uiSep)
+{
+ while (*psz != '\0' && *psz != uiSep) {
+ psz = CharNext(psz);
+ }
+ if (*psz == '\0' && uiSep != '\0') {
+ return NULL;
+ } else {
+ return psz;
+ }
+}
+#endif
diff --git a/private/sdktools/ddespy/ddespy.def b/private/sdktools/ddespy/ddespy.def
new file mode 100644
index 000000000..0cf6c2727
--- /dev/null
+++ b/private/sdktools/ddespy/ddespy.def
@@ -0,0 +1,32 @@
+NAME DdeSpy
+
+DESCRIPTION 'Sample Microsoft Windows Application'
+
+EXETYPE WINDOWS ; required for all Windows applications
+
+STUB 'WINSTUB.EXE' ; Generates error message if application
+ ; is run without Windows
+
+;CODE can be moved in memory and discarded/reloaded
+CODE PRELOAD MOVEABLE DISCARDABLE
+
+;DATA must be MULTIPLE if program can be invoked more than once
+DATA PRELOAD MOVEABLE MULTIPLE
+
+
+HEAPSIZE 4096
+STACKSIZE 5120 ; recommended minimum for Windows applications
+
+
+; All functions that will be called by any Windows routine
+; MUST be exported.
+
+EXPORTS
+ MainWndProc @1 ; name of window processing function
+ About @2 ; name of "About" processing function
+ OpenDlg @3
+ StrWndProc @4
+ DdeCallback @5
+ MarkDlgProc @6
+ MCLBClientWndProc @7
+ FilterDlgProc @8
diff --git a/private/sdktools/ddespy/ddespy.dlg b/private/sdktools/ddespy/ddespy.dlg
new file mode 100644
index 000000000..c5af5df84
--- /dev/null
+++ b/private/sdktools/ddespy/ddespy.dlg
@@ -0,0 +1,75 @@
+1 DLGINCLUDE "ddespy.h"
+
+IDD_ABOUTBOX DIALOG 25, 23, 184, 78
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "About DdeSpy"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ CTEXT "Microsoft Windows", -1, 0, 5, 184, 8
+ CTEXT "DdeSpy", -1, 0, 15, 184, 8
+ CTEXT "Version 3.1", -1, 0, 34, 184, 8
+ CTEXT "Copyright 1991 Microsoft Corp.", -1, 0, 47, 184, 9
+ DEFPUSHBUTTON "OK", IDS_DEFAULT_OUTPUT_FNAME, 76, 60, 32, 14, WS_GROUP
+ ICON "", -1, 25, 14, 16, 21
+END
+
+IDD_OPEN DIALOG 11, 51, 215, 44
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Set Output File Name"
+BEGIN
+ EDITTEXT BUFFER_SIZE, 7, 6, 202, 13, ES_AUTOHSCROLL
+ DEFPUSHBUTTON "&Set file", IDS_DEFAULT_OUTPUT_FNAME, 25, 24, 74, 14
+ PUSHBUTTON "&No file", IDS_INIFNAME, 115, 24, 75, 14
+END
+
+IDD_VALUEENTRY DIALOG 33, 29, 116, 46
+STYLE WS_POPUP | WS_CAPTION
+CAPTION "Value Entry Dialog"
+BEGIN
+ EDITTEXT IDM_MSGF_0, 54, 6, 56, 12
+ DEFPUSHBUTTON "&Ok", IDS_DEFAULT_OUTPUT_FNAME, 7, 25, 38, 14
+ PUSHBUTTON "&Cancel", IDS_INIFNAME, 72, 24, 38, 14
+ RTEXT "Value:", IDM_MSGF_1, 6, 8, 46, 8, NOT WS_GROUP
+END
+
+IDD_MSGFILTERS DIALOG 6, 18, 311, 118
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Filter Options"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ GROUPBOX "Messages", -1, 6, 2, 100, 105, WS_GROUP
+ AUTOCHECKBOX "WM_DDE_ACK", IDRB_WM_DDE_ACK, 14, 14, 90, 10
+ AUTOCHECKBOX "WM_DDE_ADVISE", IDRB_WM_DDE_ADVISE, 14, 24, 90, 10
+ AUTOCHECKBOX "WM_DDE_DATA", IDRB_WM_DDE_DATA, 14, 34, 90, 10
+ AUTOCHECKBOX "WM_DDE_EXECUTE", IDRB_WM_DDE_EXECUTE, 14, 44, 90, 10
+ AUTOCHECKBOX "WM_DDE_INITIATE", IDRB_WM_DDE_INITIATE, 14, 54, 79, 10
+ AUTOCHECKBOX "WM_DDE_POKE", IDRB_WM_DDE_POKE, 14, 64, 90, 10
+ AUTOCHECKBOX "WM_DDE_REQUEST", IDRB_WM_DDE_REQUEST, 14, 74, 90, 10
+ AUTOCHECKBOX "WM_DDE_TERMINATE", IDRB_WM_DDE_TERMINATE, 14, 84, 90,
+ 10
+ AUTOCHECKBOX "WM_DDE_UNADVISE", IDRB_WM_DDE_UNADVISE, 14, 94, 90, 10
+ GROUPBOX "Callbacks", -1, 109, 2, 195, 96, WS_GROUP
+ AUTOCHECKBOX "XTYP_ADVDATA", IDRB_XTYP_ADVDATA, 117, 14, 68, 10
+ AUTOCHECKBOX "XTYP_ADVREQ", IDRB_XTYP_ADVREQ, 117, 24, 64, 10
+ AUTOCHECKBOX "XTYP_ADVSTART", IDRB_XTYP_ADVSTART, 117, 34, 73, 10
+ AUTOCHECKBOX "XTYP_ADVSTOP", IDRB_XTYP_ADVSTOP, 117, 44, 68, 10
+ AUTOCHECKBOX "XTYP_ERROR", IDRB_XTYP_ERROR, 117, 54, 60, 10
+ AUTOCHECKBOX "XTYP_EXECUTE", IDRB_XTYP_EXECUTE, 117, 64, 68, 10
+ AUTOCHECKBOX "XTYP_CONNECT", IDRB_XTYP_CONNECT, 117, 74, 69, 10
+ AUTOCHECKBOX "XTYP_CONNECT_CONFIRM", IDRB_XTYP_CONNECT_CONFIRM, 117,
+ 84, 105, 10
+ AUTOCHECKBOX "XTYP_DISCONNECT", IDRB_XTYP_DISCONNECT, 203, 14, 81, 10
+ AUTOCHECKBOX "XTYP_POKE", IDRB_XTYP_POKE, 203, 24, 54, 10
+ AUTOCHECKBOX "XTYP_REGISTER", IDRB_XTYP_REGISTER, 203, 34, 71, 10
+ AUTOCHECKBOX "XTYP_REQUEST", IDRB_XTYP_REQUEST, 203, 44, 69, 10
+ AUTOCHECKBOX "XTYP_UNREGISTER", IDRB_XTYP_UNREGISTER, 203, 54, 82, 10
+ AUTOCHECKBOX "XTYP_WILDCONNECT", IDRB_XTYP_WILDCONNECT, 203, 64, 87,
+ 10
+ AUTOCHECKBOX "XTYP_XACT_COMPLETE", IDRB_XACT_COMPLETE, 203, 74, 95,
+ 10
+ AUTOCHECKBOX "Terse Output", IDRB_TERSE, 249, 103, 55, 10, WS_GROUP
+ DEFPUSHBUTTON "Ok", IDS_DEFAULT_OUTPUT_FNAME, 134, 101, 40, 14,
+ WS_GROUP
+ PUSHBUTTON "Cancel", IDS_INIFNAME, 190, 101, 40, 14
+END
+
diff --git a/private/sdktools/ddespy/ddespy.h b/private/sdktools/ddespy/ddespy.h
new file mode 100644
index 000000000..dcb11b0e6
--- /dev/null
+++ b/private/sdktools/ddespy/ddespy.h
@@ -0,0 +1,333 @@
+/*
+ * DDESPY.H
+ *
+ * Header file for DDESPY Symbols
+ */
+#define DDEMLDB
+
+#include <ddeml.h>
+#include "dialog.h"
+
+#define MH_INTCREATE 5
+#define MH_INTKEEP 6
+#define MH_INTDELETE 7
+
+#define IDI_DDESPY 100
+#define IDD_MSGFILTERS 300
+#define IDRB_WM_DDE_INITIATE 305
+#define IDRB_WM_DDE_TERMINATE 306
+#define IDRB_WM_DDE_ADVISE 307
+#define IDRB_WM_DDE_UNADVISE 308
+#define IDRB_WM_DDE_ACK 309
+#define IDRB_WM_DDE_DATA 310
+#define IDRB_WM_DDE_REQUEST 311
+#define IDRB_WM_DDE_POKE 312
+#define IDRB_WM_DDE_EXECUTE 313
+#define IDRB_XTYP_ERROR 314
+#define IDRB_XTYP_ADVDATA 315
+#define IDRB_XTYP_ADVREQ 316
+#define IDRB_XTYP_ADVSTART 317
+#define IDRB_XTYP_ADVSTOP 318
+#define IDRB_XTYP_EXECUTE 319
+#define IDRB_XTYP_CONNECT 320
+#define IDRB_XTYP_CONNECT_CONFIRM 321
+#define IDRB_XACT_COMPLETE 322
+#define IDRB_XTYP_POKE 323
+#define IDRB_XTYP_REGISTER 324
+#define IDRB_XTYP_REQUEST 325
+#define IDRB_XTYP_DISCONNECT 326
+#define IDRB_XTYP_UNREGISTER 327
+#define IDRB_XTYP_WILDCONNECT 328
+#define IDRB_TERSE 329
+
+#define IDR_ACCEL 30
+#define IDR_MENU 31
+#define IDD_VALUEENTRY 50
+#define IDD_ABOUTBOX 51
+#define IDD_OPEN 52
+#define IDM_OUTPUT_FIRST 100
+#define IDM_OUTPUT_FILE 100
+#define IDM_OUTPUT_DEBUG 101
+#define IDM_OUTPUT_SCREEN 102
+#define IDM_CLEARSCREEN 103
+#define IDM_MARK 104
+#define IDM_FILTER_FIRST 200
+#define IDM_FILTER_HSZINFO 200
+#define IDM_FILTER_INIT_TERM 201
+#define IDM_FILTER_DDEMSGS 202
+#define IDM_FILTER_CALLBACKS 203
+#define IDM_FILTER_ERRORS 204
+#define IDM_FILTER_DIALOG 205
+#define IDM_TRACK_FIRST 301
+#define IDM_TRACK_HSZS 301
+#define IDM_TRACK_CONVS 302
+#define IDM_TRACK_LINKS 303
+#define IDM_TRACK_SVRS 304
+#define IDM_TRACK_LAST 304
+#define IDM_ABOUT 401
+#define IDM_TEST 402
+
+#define IDM_MSGF_0 500
+#define IDM_MSGF_1 501
+#define IDM_MSGF_2 502
+#define IDM_MSGF_3 503
+#define IDM_MSGF_4 504
+#define IDM_MSGF_5 505
+#define IDM_MSGF_6 506
+#define IDM_MSGF_7 507
+#define IDM_MSGF_8 508
+
+#define IDM_CBF_0 600
+#define IDM_CBF_1 601
+#define IDM_CBF_2 602
+#define IDM_CBF_3 603
+#define IDM_CBF_4 604
+#define IDM_CBF_5 605
+#define IDM_CBF_6 606
+#define IDM_CBF_7 607
+#define IDM_CBF_8 608
+#define IDM_CBF_9 609
+#define IDM_CBF_10 610
+#define IDM_CBF_11 611
+#define IDM_CBF_12 612
+#define IDM_CBF_13 613
+#define IDM_CBF_14 614
+
+#define IDS_TITLE 0
+#define IDS_DEFAULT_OUTPUT_FNAME 1
+#define IDS_INIFNAME 2
+#define IDS_CLASS 3
+#define IDS_HUH 4
+#define IDS_ZERO 5
+#define IDS_CRLF 6
+#define IDS_TRACKTITLE_1 7
+#define IDS_TRACKTITLE_2 8
+#define IDS_TRACKTITLE_3 9
+#define IDS_TRACKTITLE_4 10
+#define IDS_TRACKHEADING_1 11
+#define IDS_TRACKHEADING_2 12
+#define IDS_TRACKHEADING_3 13
+#define IDS_TRACKHEADING_4 14
+#define IDS_QCLOSEFILE_TEXT 15
+#define IDS_QCLOSEFILE_CAPTION 16
+#define IDS_ACTION_CLEANEDUP 17
+#define IDS_ACTION_DESTROYED 18
+#define IDS_ACTION_INCREMENTED 19
+#define IDS_ACTION_CREATED 20
+#define IDS_SENT 21
+#define IDS_POSTED 22
+#define IDS_INPUT_DATA 23
+#define IDS_TABDDD 24
+#define IDS_OUTPUT_DATA 25
+#define IDS_WARM 26
+#define IDS_HOT 27
+#define IDS_UNKNOWN_CALLBACK 28
+#define IDS_APPIS 29
+#define IDS_TOPICIS 30
+#define IDS_ITEMIS 31
+#define IDS_OR 32
+#define IDS_FACKREQ 33
+#define IDS_DEFERUPD 34
+#define IDS_FACK 35
+#define IDS_FBUSY 36
+#define IDS_FRELEASE 37
+#define IDS_FREQUESTED 38
+#define IDS_ERRST0 39
+#define IDS_ERRST1 40
+#define IDS_ERRST2 41
+#define IDS_ERRST3 42
+#define IDS_ERRST4 43
+#define IDS_ERRST5 44
+#define IDS_ERRST6 45
+#define IDS_ERRST7 46
+#define IDS_ERRST8 47
+#define IDS_ERRST9 48
+#define IDS_ERRST10 49
+#define IDS_ERRST11 50
+#define IDS_ERRST12 51
+#define IDS_ERRST13 52
+#define IDS_ERRST14 53
+#define IDS_ERRST15 54
+#define IDS_ERRST16 55
+#define IDS_ERRST17 56
+#define IDS_MSG0 57
+#define IDS_MSG1 58
+#define IDS_MSG2 59
+#define IDS_MSG3 60
+#define IDS_MSG4 61
+#define IDS_MSG5 62
+#define IDS_MSG6 63
+#define IDS_MSG7 64
+#define IDS_MSG8 65
+#define IDS_TYPE0 66
+#define IDS_TYPE1 67
+#define IDS_TYPE2 68
+#define IDS_TYPE3 69
+#define IDS_TYPE4 70
+#define IDS_TYPE5 71
+#define IDS_TYPE6 72
+#define IDS_TYPE7 73
+#define IDS_TYPE8 74
+#define IDS_TYPE9 75
+#define IDS_TYPE10 76
+#define IDS_TYPE11 77
+#define IDS_TYPE12 78
+#define IDS_TYPE13 79
+#define IDS_TYPE14 80
+#define IDS_TYPE15 81
+#define IDS_INVALID_FNAME 82
+#define IDS_PROF_OUT_FILE 83
+#define IDS_PROF_OUT_DEBUG 84
+#define IDS_PROF_OUT_SCREEN 85
+#define IDS_PROF_MONITOR_STRINGHANDLES 86
+#define IDS_PROF_MONITOR_INITIATES 87
+#define IDS_PROF_MONITOR_DDE_MESSAGES 88
+#define IDS_PROF_MONITOR_CALLBACKS 89
+#define IDS_PROF_MONITOR_ERRORS 90
+#define IDS_PROF_TRACK_STRINGHANDLES 91
+#define IDS_PROF_TRACK_LINKS 92
+#define IDS_PROF_TRACK_CONVERSATIONS 93
+#define IDS_PROF_TRACK_SERVICES 94
+#define IDS_PROF_TERSE 95
+#define IDS_YES 96
+#define IDS_NO 97
+#define IDS_MARKDLGTITLE 98
+#define IDS_SEPERATOR 99
+#define IDS_MARKTEXT 100
+#define IDS_LISTCLASS 101
+#define IDS_LBOX 102
+#define IDS_WILD 103
+#define IDS_STRINGCLASS 104
+#define IDS_FMT_CB1 105
+#define IDS_FMT_CB2 106
+#define IDS_FMT_CTXT1 107
+#define IDS_FMT_DATAIS1 108
+#define IDS_FMT_ER1 109
+#define IDS_FMT_EXEC1 110
+#define IDS_FMT_MSG1 111
+#define IDS_FMT_MSG2 112
+#define IDS_FMT_STATUSIS 113
+#define IDS_FMT_TRS_CB1 114
+#define IDS_FMT_TRS_CB2 115
+#define IDS_FMT_TRS_CTXT1 116
+#define IDS_FMT_TRS_DATAIS1 117
+#define IDS_FMT_TRS_ER1 118
+#define IDS_FMT_TRS_EXEC1 119
+#define IDS_FMT_TRS_MSG1 120
+#define IDS_FMT_TRS_MSG2 121
+#define IDS_FMT_TRS_STATUSIS 122
+#define IDS_FMT_SH_MSG1 123
+#define IDS_BADATOM 124
+#define IDS_LAST 124
+
+#define T_ATOM 0x0001
+#define T_OPTIONHANDLE 0x0002
+#define T_FORMAT 0x0004
+#define T_STATUS 0x0008
+#define T_DATAHANDLE 0x0010
+#define T_STRINGHANDLE 0x0020
+#define T_VALUE 0x0040
+#define T_APP 0x0080
+#define T_TOPIC 0x0100
+#define T_ITEM 0x0200
+#define T_OR 0x0400
+
+
+#define IO_FILE 0
+#define IO_DEBUG 1
+#define IO_SCREEN 2
+#define IO_COUNT 3
+
+#define IF_HSZ 0
+#define IF_SEND 1
+#define IF_POST 2
+#define IF_CB 3
+#define IF_ERR 4
+
+#define IF_COUNT 5
+
+#define IT_HSZS 0
+#define IT_CONVS 1
+#define IT_LINKS 2
+#define IT_SVRS 3
+
+#define IT_COUNT 4
+
+#define MAX_FNAME MAX_PATH
+#define BUFFER_SIZE 400
+#define MAX_MARK 32
+#define MAX_DISPDATA 48 // max bytes of non-text data to dump
+
+#define CLINES 1000
+#define CCHARS 200
+
+extern HINSTANCE hInst;
+
+/* macro definitions */
+#define MyAlloc(cb) (LPTSTR)LocalAlloc(LPTR, (cb))
+#define MyFree(p) (LocalUnlock((HANDLE)(p)), LocalFree((HANDLE)(p)))
+#define RefString(id) (LPTSTR)apszResources[id]
+#define Type2String(type) apszResources[IDS_TYPE0 + ((type & XTYP_MASK) >> XTYP_SHIFT)]
+#define MPRT(b) (isprint(b) ? (b) : '.')
+
+/* prototype definitions */
+BOOL InitApplication(HANDLE);
+BOOL InitInstance(HANDLE, INT);
+VOID CloseApp(VOID);
+LONG CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
+BOOL CALLBACK About(HWND, UINT, WPARAM, LPARAM);
+BOOL SetFilters(VOID);
+BOOL CALLBACK OpenDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
+BOOL CALLBACK FilterDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
+LPTSTR DisectMsgLP(UINT msg, MONMSGSTRUCT *pmms, LPTSTR pszBuf);
+LPTSTR DisectWord(UINT type, UINT data, DDEML_MSG_HOOK_DATA *pdmhd, LPTSTR pstr);
+LPTSTR pdf(UINT fmt);
+LPTSTR DumpFormat(UINT fmt, LPTSTR pstr);
+LPTSTR DdeMsg2String(UINT msg);
+LPTSTR Error2String(UINT error);
+LPTSTR DumpData(LPBYTE pData, UINT cb, TCHAR *szBuf, UINT fmt);
+LPTSTR GetHszName(HSZ hsz);
+VOID OutputString(LPTSTR pstr);
+VOID GetProfile(VOID);
+VOID SaveProfile(VOID);
+BOOL GetProfileBoolean(LPTSTR pszKey, BOOL fDefault);
+VOID SetProfileBoolean(LPTSTR pszKey, BOOL fSet);
+HDDEDATA CALLBACK DdeCallback(UINT wType, UINT wFmt, HCONV hConv, HSZ hsz1,
+ HSZ hsz2, HDDEDATA hData, UINT lData1, UINT lData2);
+INT FAR DoDialog(LPTSTR lpTemplateName, DLGPROC lpDlgProc, UINT param,
+ BOOL fRememberFocus, HWND hwndParent, HANDLE hInst);
+BOOL CALLBACK MarkDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+/* testsubs.c prototypes */
+
+/* StringWindow structure */
+typedef struct {
+ INT cchLine;
+ INT cLine;
+ INT offBuffer;
+ INT offBufferMax;
+ INT offBottomLine;
+ INT offOutput;
+ INT cBottomLine;
+ INT cLeftChar;
+} STRWND;
+
+
+BOOL InitTestSubs(VOID);
+VOID CloseTestSubs(HANDLE hInst);
+VOID NextLine(STRWND *psw);
+VOID DrawString(HWND hwnd, TCHAR *sz);
+VOID ClearScreen(STRWND *psw);
+LONG CALLBACK StrWndProc(HWND hwnd, UINT msg, WPARAM wParam, UINT lParam);
+VOID scroll(HWND hwnd, UINT msg, UINT sliderpos, UINT style);
+BOOL StrWndCreate(HWND hwnd, INT cchLine, INT cLine);
+VOID PaintStrWnd(HWND hwnd, LPPAINTSTRUCT pps);
+
+#ifdef DBCS
+#define strchr My_mbschr
+#ifdef stricmp
+#undef stricmp
+#endif
+#define stricmp lstrcmpi
+LPTSTR _CRTAPI1 My_mbschr(LPTSTR, TCHAR);
+#endif // DBCS
diff --git a/private/sdktools/ddespy/ddespy.ico b/private/sdktools/ddespy/ddespy.ico
new file mode 100644
index 000000000..ee940ec01
--- /dev/null
+++ b/private/sdktools/ddespy/ddespy.ico
Binary files differ
diff --git a/private/sdktools/ddespy/ddespy.rc b/private/sdktools/ddespy/ddespy.rc
new file mode 100644
index 000000000..248b8ec63
--- /dev/null
+++ b/private/sdktools/ddespy/ddespy.rc
@@ -0,0 +1,186 @@
+#include "windows.h"
+#include "ddespy.h"
+
+rcinclude ddespy.dlg
+
+IDI_DDESPY ICON ddespy.ico
+
+IDR_MENU MENU
+BEGIN
+ POPUP "&Output",
+ BEGIN
+ MENUITEM "&File...\tCtrl-F", IDM_OUTPUT_FILE
+ MENUITEM "&Debug Terminal\tCtrl-D" IDM_OUTPUT_DEBUG
+ MENUITEM "&Screen\tCtrl-S", IDM_OUTPUT_SCREEN
+ MENUITEM SEPARATOR
+ MENUITEM "&Clear Screen", IDM_CLEARSCREEN
+ MENUITEM "&Mark...", IDM_MARK
+ END
+ POPUP "&Monitor",
+ BEGIN
+ MENUITEM "String &handle data", IDM_FILTER_HSZINFO
+ MENUITEM "&Sent DDE messages", IDM_FILTER_INIT_TERM
+ MENUITEM "&Posted DDE messages", IDM_FILTER_DDEMSGS
+ MENUITEM "&Callbacks", IDM_FILTER_CALLBACKS
+ MENUITEM "&Errors", IDM_FILTER_ERRORS
+ MENUITEM "&Filters...", IDM_FILTER_DIALOG
+ END
+ POPUP "&Track",
+ BEGIN
+ MENUITEM "&String Handles", IDM_TRACK_HSZS
+ MENUITEM "&Conversations", IDM_TRACK_CONVS
+ MENUITEM "&Links", IDM_TRACK_LINKS
+ MENUITEM "Ser&vices", IDM_TRACK_SVRS
+ END
+ MENUITEM "&About...", IDM_ABOUT
+END
+
+IDR_ACCEL ACCELERATORS
+BEGIN
+ "F" , IDM_OUTPUT_FILE, VIRTKEY, CONTROL
+ "D" , IDM_OUTPUT_DEBUG, VIRTKEY, CONTROL
+ "S" , IDM_OUTPUT_SCREEN, VIRTKEY, CONTROL
+END
+
+STRINGTABLE
+BEGIN
+ IDS_TITLE ,"DDESpy"
+ IDS_DEFAULT_OUTPUT_FNAME ,"ddespy.txt"
+ IDS_INIFNAME ,"ddespy.ini"
+ IDS_CLASS ,"DdeSpyWClass"
+ IDS_HUH ,"?"
+ IDS_ZERO ,"0"
+ IDS_CRLF ,"\r\n"
+ IDS_TRACKTITLE_1 ,"String Handles"
+ IDS_TRACKTITLE_2 ,"Active Conversations"
+ IDS_TRACKTITLE_3 ,"Active Links"
+ IDS_TRACKTITLE_4 ,"Registered Servers"
+ IDS_TRACKHEADING_1 ,"Handle\tCount\tString"
+ IDS_TRACKHEADING_2 ,"Service\tTopic\tClient\tServer"
+ IDS_TRACKHEADING_3 ,"Service\tTopic\tItem\tFormat\tType\tClient\tServer"
+ IDS_TRACKHEADING_4 ,"Service\tInstance Service"
+ IDS_QCLOSEFILE_TEXT ,"%s is already open for debug output. Do you wish to close it and open another file?"
+ IDS_QCLOSEFILE_CAPTION ,"Warning!"
+ IDS_ACTION_CLEANEDUP ,"Cleaned up"
+ IDS_ACTION_DESTROYED ,"Destroyed"
+ IDS_ACTION_INCREMENTED ,"Incremented"
+ IDS_ACTION_CREATED ,"Created"
+ IDS_SENT ,"Sent"
+ IDS_POSTED ,"Posted"
+ IDS_INPUT_DATA ,"\tInput data="
+ IDS_TABDDD ,"\t..."
+ IDS_OUTPUT_DATA ,"\tOutput data="
+ IDS_WARM ,"Warm"
+ IDS_HOT ,"Hot"
+ IDS_UNKNOWN_CALLBACK ,"Unknown callback"
+ IDS_APPIS ,"App="
+ IDS_TOPICIS ,"Topic="
+ IDS_ITEMIS ,"Item="
+ IDS_OR ," or "
+ IDS_FACKREQ ,"fAckReq "
+ IDS_DEFERUPD ,"fDeferUpd "
+ IDS_FACK ,"fAck "
+ IDS_FBUSY ,"fBusy "
+ IDS_FRELEASE ,"fRelease "
+ IDS_FREQUESTED ,"fRequested "
+ IDS_ERRST0 ,"Advacktimeout"
+ IDS_ERRST1 ,"Busy"
+ IDS_ERRST2 ,"Dataacktimeout"
+ IDS_ERRST3 ,"Dll_not_initialized"
+ IDS_ERRST4 ,"Dll_usage"
+ IDS_ERRST5 ,"Execacktimeout"
+ IDS_ERRST6 ,"Invalidparameter"
+ IDS_ERRST7 ,"Low Memory warning"
+ IDS_ERRST8 ,"Memory_error"
+ IDS_ERRST9 ,"Notprocessed"
+ IDS_ERRST10 ,"No_conv_established"
+ IDS_ERRST11 ,"Pokeacktimeout"
+ IDS_ERRST12 ,"Postmsg_failed"
+ IDS_ERRST13 ,"Reentrancy"
+ IDS_ERRST14 ,"Server_died"
+ IDS_ERRST15 ,"Sys_error"
+ IDS_ERRST16 ,"Unadvacktimeout"
+ IDS_ERRST17 ,"Unfound_queue_id"
+ IDS_MSG0 ,"Initiate"
+ IDS_MSG1 ,"Terminate"
+ IDS_MSG2 ,"Advise"
+ IDS_MSG3 ,"Unadvise"
+ IDS_MSG4 ,"Ack"
+ IDS_MSG5 ,"Data"
+ IDS_MSG6 ,"Request"
+ IDS_MSG7 ,"Poke"
+ IDS_MSG8 ,"Execute"
+ IDS_TYPE0 ,"Error"
+ IDS_TYPE1 ,"Advdata"
+ IDS_TYPE2 ,"Advreq"
+ IDS_TYPE3 ,"Advstart"
+ IDS_TYPE4 ,"Advstop"
+ IDS_TYPE5 ,"Execute"
+ IDS_TYPE6 ,"Connect"
+ IDS_TYPE7 ,"Connect_confirm"
+ IDS_TYPE8 ,"Xact_complete"
+ IDS_TYPE9 ,"Poke"
+ IDS_TYPE10 ,"Register"
+ IDS_TYPE11 ,"Request"
+ IDS_TYPE12 ,"Disconnect"
+ IDS_TYPE13 ,"Unregister"
+ IDS_TYPE14 ,"Wildconnect"
+ IDS_TYPE15 ,"Monitor"
+ IDS_INVALID_FNAME ,"Invalid filename."
+ IDS_PROF_OUT_FILE ,"output.file"
+ IDS_PROF_OUT_DEBUG ,"output.debug"
+ IDS_PROF_OUT_SCREEN ,"output.screen"
+ IDS_PROF_MONITOR_STRINGHANDLES ,"monitor.stringhandles"
+ IDS_PROF_MONITOR_INITIATES ,"monitor.initiates/terminates"
+ IDS_PROF_MONITOR_DDE_MESSAGES ,"monitor.messages"
+ IDS_PROF_MONITOR_CALLBACKS ,"monitor.callbacks"
+ IDS_PROF_MONITOR_ERRORS ,"monitor.errors"
+ IDS_PROF_TRACK_STRINGHANDLES ,"track.stringhandles"
+ IDS_PROF_TRACK_LINKS ,"track.links"
+ IDS_PROF_TRACK_CONVERSATIONS ,"track.conversations"
+ IDS_PROF_TRACK_SERVICES ,"track.services"
+ IDS_PROF_TERSE ,"terse"
+ IDS_YES ,"yes"
+ IDS_NO ,"no"
+ IDS_MARKDLGTITLE ,"Insert Mark"
+ IDS_SEPERATOR ,"------"
+ IDS_MARKTEXT ,"Mark Text:"
+ IDS_LISTCLASS ,"MCLBClientWClass"
+ IDS_LBOX ,"LISTBOX"
+ IDS_WILD ,"*"
+ IDS_STRINGCLASS ,"StringWindow"
+ IDS_FMT_CB1 ,"Task:0x%x Time:%ld Callback:\r\n\tType=%ws, "
+ IDS_FMT_CB2 ,", hConv=0x%lx, hsz1=0x%lx(\""%ws\"")\r\n\thsz2=0x%lx(\""%ws\""), hData=0x%lx, dwData1=0x%lx, dwData2=0x%lx\r\n\treturn=0x%lx"
+ IDS_FMT_CTXT1 ,"\tContext = (wFlags=%ld, wCountryID=%ld, iCodePage=%ld, dwLangID=%ld,\r\n\tdwSecurity=%ld, ImpersonationLevel=%d, ContextTrackingMode=%d,\r\n\tEffectiveOnly=%ld)"
+ IDS_FMT_DATAIS1 ,"\r\n\tData="
+ IDS_FMT_ER1 ,"Task:0x%x Time:%ld Error: #%x = %ws"
+ IDS_FMT_EXEC1 ,"Execute command=\""%ws\"""
+ IDS_FMT_MSG1 ,"Task:0x%x Time:%ld hwndTo=0x%x Message(%ws)=%ws:"
+ IDS_FMT_MSG2 ,"\thwndFrom=0x%x, "
+ IDS_FMT_STATUSIS ,"status=%x("
+ IDS_FMT_TRS_CB1 ,"[%x:%ld] CB(%ws, "
+ IDS_FMT_TRS_CB2 ,", %lx, %lx(\""%ws\"") %lx(\""%ws\""), %lx, %lx, %lx)=%lx"
+ IDS_FMT_TRS_CTXT1 ,"\tContext = (%ld, %ld, %ld, %ld, %ld, %d, %d, %ld)"
+ IDS_FMT_TRS_DATAIS1 ," Data="
+ IDS_FMT_TRS_ER1 ,"[%x:%ld] Error: #%x = %ws"
+ IDS_FMT_TRS_EXEC1 ,"Exec=\""%ws\"""
+ IDS_FMT_TRS_MSG1 ,"[%x:%ld] %x->%x %ws %ws:"
+ IDS_FMT_TRS_MSG2 ,"\t"
+ IDS_FMT_TRS_STATUSIS ,"S=%x("
+ IDS_FMT_SH_MSG1 ,"Task:0x%x, Time:%ld, String Handle %s: %lx(%s)"
+#ifdef JAPAN
+ IDS_BADATOM ,"sȱ (0x%x)"
+#else
+ IDS_BADATOM ,"Bad Atom (0x%x)"
+#endif
+END
+
+#include <ntverp.h>
+
+#define VER_FILETYPE VFT_APP
+#define VER_FILESUBTYPE VFT2_UNKNOWN
+#define VER_FILEDESCRIPTION_STR "DDE Spy Debugging Applet"
+#define VER_INTERNALNAME_STR "ddespy\0"
+#define VER_ORIGINALFILENAME_STR "ddespy.exe\0"
+
+#include "common.ver"
diff --git a/private/sdktools/ddespy/dialog.h b/private/sdktools/ddespy/dialog.h
new file mode 100644
index 000000000..01b526e54
--- /dev/null
+++ b/private/sdktools/ddespy/dialog.h
@@ -0,0 +1,10 @@
+/*
+ * DIALOG.H
+ *
+ * Header file for Dialogs
+ */
+
+
+#define IDC_EDIT 400
+#define IDEF_VALUE 500
+#define IDTX_VALUE 501
diff --git a/private/sdktools/ddespy/globals.h b/private/sdktools/ddespy/globals.h
new file mode 100644
index 000000000..358d014a0
--- /dev/null
+++ b/private/sdktools/ddespy/globals.h
@@ -0,0 +1,27 @@
+/*
+ * GLOBALS.H
+ *
+ * Header file for DDESPY Global prototypes and Variables
+ */
+
+extern HINSTANCE hInst;
+extern HICON hIcon;
+extern HWND hWndString;
+extern INT fhOutput;
+extern OFSTRUCT ofsOpen;
+extern CHAR OpenName[MAX_FNAME + 1];
+extern CHAR TBuf[BUFFER_SIZE];
+extern CHAR TBuf2[BUFFER_SIZE];
+extern CHAR szNULL[];
+extern PSTR apszResources[IDS_LAST];
+extern PFNCALLBACK pfnDdeCallback;
+extern HWND hwndTrack[IT_COUNT];
+extern LPTSTR TrackTitle[IT_COUNT];
+extern LPTSTR TrackHeading[IT_COUNT];
+
+extern struct { /* profile data structure */
+ BOOL fOutput[IO_COUNT];
+ BOOL fFilter[IF_COUNT];
+ BOOL fTrack[IT_COUNT];
+} pro;
+
diff --git a/private/sdktools/ddespy/lists.c b/private/sdktools/ddespy/lists.c
new file mode 100644
index 000000000..5e780bc41
--- /dev/null
+++ b/private/sdktools/ddespy/lists.c
@@ -0,0 +1,433 @@
+/*
+ * LISTS.C
+ *
+ * This file implements a generalized multi-collumn listbox with a standard
+ * frame window.
+ */
+#define UNICODE
+#include <windows.h>
+#include <windowsx.h>
+#include <string.h>
+#include <stdlib.h>
+#include "ddespy.h"
+#include "globals.h"
+#include "lists.h"
+
+int CompareItems(LPTSTR psz1, LPTSTR psz2, INT SortCol, INT cCols);
+int CmpCols(LPTSTR psz1, LPTSTR psz2, INT SortCol);
+void DrawLBItem(LPDRAWITEMSTRUCT lpdis);
+long CALLBACK MCLBClientWndProc(HWND hwnd, UINT msg, WPARAM wParam, LONG lPAram);
+
+UINT cyHeading;
+
+
+#ifdef UNICODE
+
+#define atoi atoiW
+
+
+//*********************************************************************
+//
+// atoiW
+//
+// Unicode version of atoi.
+//
+
+INT atoiW (LPTSTR s) {
+ INT i = 0;
+
+ while (isdigit (*s)) {
+ i = i*10 + (BYTE)*s - TEXT('0');
+ s++;
+ }
+ return i;
+}
+
+#endif
+
+HWND CreateMCLBFrame(
+ HWND hwndParent,
+ LPTSTR lpszTitle, // frame title string
+ UINT dwStyle, // frame styles
+ HICON hIcon,
+ HBRUSH hbrBkgnd, // background for heading.
+ LPTSTR lpszHeadings) // tab delimited list of headings. The number of
+ // headings indicate the number of collumns.
+{
+ static BOOL fRegistered = FALSE;
+ MCLBCREATESTRUCT mclbcs;
+
+ if (!fRegistered) {
+ WNDCLASS wc;
+ HDC hdc;
+ TEXTMETRIC tm;
+
+ wc.style = WS_OVERLAPPED | CS_HREDRAW | CS_VREDRAW;
+ wc.lpfnWndProc = MCLBClientWndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 4;
+ wc.hInstance = hInst;
+ wc.hIcon = hIcon;
+ wc.hCursor = NULL;
+ wc.hbrBackground = hbrBkgnd;
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = (LPCTSTR) RefString(IDS_LISTCLASS);
+ RegisterClass(&wc);
+
+ hdc = GetDC(GetDesktopWindow());
+ GetTextMetrics(hdc, &tm);
+ cyHeading = tm.tmHeight;
+ ReleaseDC(GetDesktopWindow(), hdc);
+
+ fRegistered = TRUE;
+ }
+ mclbcs.lpszHeadings = lpszHeadings;
+
+ return(CreateWindow((LPCTSTR) RefString(IDS_LISTCLASS),
+ (LPCTSTR) lpszTitle, dwStyle,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ hwndParent, NULL, hInst, (LPVOID)&mclbcs));
+}
+
+
+LONG CALLBACK MCLBClientWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ MCLBSTRUCT *pmclb;
+ RECT rc;
+ INT i;
+
+ if (msg == WM_CREATE) {
+ LPTSTR psz;
+ MCLBCREATESTRUCT FAR *pcs;
+
+ pcs = (MCLBCREATESTRUCT FAR *)((LPCREATESTRUCT)lParam)->lpCreateParams;
+ pmclb = (MCLBSTRUCT *)LocalAlloc(LPTR, sizeof(MCLBSTRUCT));
+ psz = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR)
+ * (lstrlen(pcs->lpszHeadings) + 1));
+ lstrcpy((LPTSTR)psz, pcs->lpszHeadings);
+ pmclb->pszHeadings = psz;
+ pmclb->cCols = 1;
+ while (*psz) {
+ if (*psz == '\t') {
+ pmclb->cCols++;
+ }
+ psz++;
+ }
+ pmclb->SortCol = 0;
+ SetWindowLong(hwnd, 0, (UINT)pmclb);
+ GetClientRect(hwnd, &rc);
+ pmclb->hwndLB = CreateWindow((LPCTSTR) RefString(IDS_LBOX),
+ (LPCTSTR) szNULL,
+ MYLBSTYLE | WS_VISIBLE,
+ 0, 0, 0, 0, hwnd, (HMENU)pmclb->cCols, hInst, NULL);
+ return(pmclb->hwndLB ? 0 : -1);
+ }
+
+ pmclb = (MCLBSTRUCT *)GetWindowLong(hwnd, 0);
+
+ switch (msg) {
+ case WM_PAINT:
+ {
+ PAINTSTRUCT ps;
+ DRAWITEMSTRUCT dis;
+
+ BeginPaint(hwnd, &ps);
+ SetBkMode(ps.hdc, TRANSPARENT);
+ dis.hwndItem = hwnd;
+ dis.hDC = ps.hdc;
+ GetClientRect(hwnd, &dis.rcItem);
+ dis.rcItem.bottom = dis.rcItem.top + cyHeading;
+ dis.CtlType = ODT_BUTTON; // hack to avoid erasure
+ dis.CtlID = pmclb->cCols;
+ dis.itemID = 0;
+ dis.itemAction = ODA_DRAWENTIRE;
+ dis.itemData = (UINT)(LPTSTR)pmclb->pszHeadings;
+ dis.itemState = 0;
+ DrawLBItem(&dis);
+ EndPaint(hwnd, &ps);
+ }
+ break;
+
+ case WM_SIZE:
+ MoveWindow(pmclb->hwndLB, 0, cyHeading, LOWORD(lParam),
+ HIWORD(lParam) - cyHeading, TRUE);
+ break;
+
+ case WM_LBUTTONDOWN:
+ {
+ HWND hwndLB;
+ INT i;
+
+ // determine which collumn the mouse landed and sort on that collumn.
+
+ SendMessage(hwnd, WM_SETREDRAW, 0, 0);
+ GetClientRect(hwnd, &rc);
+ InflateRect(&rc, -1, -1);
+ pmclb->SortCol = LOWORD(lParam) * pmclb->cCols / (rc.right - rc.left);
+ hwndLB = CreateWindow((LPCTSTR) RefString(IDS_LBOX),
+ (LPCTSTR) szNULL, MYLBSTYLE, 1, cyHeading + 1,
+ rc.right - rc.left, rc.bottom - rc.top - cyHeading,
+ hwnd, (HMENU)pmclb->cCols, hInst, NULL);
+ for (i = (INT)SendMessage(pmclb->hwndLB, LB_GETCOUNT, 0, 0); i;
+ i--) {
+ SendMessage(hwndLB, LB_ADDSTRING, 0,
+ SendMessage(pmclb->hwndLB, LB_GETITEMDATA, i - 1, 0));
+ SendMessage(pmclb->hwndLB, LB_SETITEMDATA, i - 1, 0);
+ }
+ ShowWindow(hwndLB, SW_SHOW);
+ ShowWindow(pmclb->hwndLB, SW_HIDE);
+ DestroyWindow(pmclb->hwndLB);
+ pmclb->hwndLB = hwndLB;
+ SendMessage(hwnd, WM_SETREDRAW, 1, 0);
+ InvalidateRect(hwnd, NULL, FALSE);
+ }
+ break;
+
+ case WM_DELETEITEM:
+
+ if ((UINT)((LPDELETEITEMSTRUCT)lParam)->itemData)
+ LocalFree(LocalHandle((PVOID)((LPDELETEITEMSTRUCT)lParam)->itemData));
+ break;
+
+ case WM_MEASUREITEM:
+ ((LPMEASUREITEMSTRUCT)lParam)->itemHeight = cyHeading;
+ break;
+
+ case WM_DRAWITEM:
+ GetClientRect(hwnd, &rc);
+ // This fudge makes the collumns line up with the heading.
+ ((LPDRAWITEMSTRUCT)lParam)->rcItem.right = rc.right;
+ DrawLBItem((LPDRAWITEMSTRUCT)lParam);
+ return(DefWindowProc(hwnd, msg, wParam, lParam));
+ break;
+
+ case WM_COMPAREITEM:
+ return(CompareItems((LPTSTR)((LPCOMPAREITEMSTRUCT)lParam)->itemData1,
+ (LPTSTR)((LPCOMPAREITEMSTRUCT)lParam)->itemData2,
+ pmclb->SortCol,
+ pmclb->cCols));
+ break;
+
+ case WM_DESTROY:
+ LocalFree(LocalHandle((PVOID)pmclb->pszHeadings));
+ LocalFree(LocalHandle((PVOID)pmclb));
+ break;
+
+ case WM_CLOSE:
+ for (i = 0; i < IT_COUNT && (hwndTrack[i] != hwnd); i++) {
+ ;
+ }
+ pro.fTrack[i] = FALSE;
+ hwndTrack[i] = NULL;
+ SetFilters();
+ DestroyWindow(hwnd);
+ break;
+
+ default:
+ return(DefWindowProc(hwnd, msg, wParam, lParam));
+ }
+}
+
+
+
+
+/*
+ * Make this return FALSE if addition not needed.
+ *
+ * if pszSearch != NULL, searches for pszSearch - collumns may contain
+ * wild strings - TEXT("*")
+ * If found, the string is removed from the LB.
+ * Adds pszReplace to LB.
+ */
+VOID AddMCLBText(LPTSTR pszSearch, LPTSTR pszReplace, HWND hwndLBFrame)
+{
+ MCLBSTRUCT *pmclb;
+ INT lit;
+ LPTSTR psz;
+
+ pmclb = (MCLBSTRUCT *)GetWindowLong(hwndLBFrame, 0);
+
+ SendMessage(pmclb->hwndLB, WM_SETREDRAW, 0, 0);
+ if (pszSearch != NULL) {
+ lit = (INT)SendMessage(pmclb->hwndLB, LB_FINDSTRING, (WPARAM)-1, (LONG)(LPTSTR)pszSearch);
+ if (lit >= 0) {
+ SendMessage(pmclb->hwndLB, LB_DELETESTRING, lit, 0);
+ }
+ }
+ psz = (LPTSTR)LocalAlloc(LPTR, sizeof(TCHAR) * (lstrlen(pszReplace) + 1));
+ lstrcpy(psz, pszReplace);
+ SendMessage(pmclb->hwndLB, WM_SETREDRAW, 1, 0);
+ SendMessage(pmclb->hwndLB, LB_ADDSTRING, 0, (LONG)(LPTSTR)psz);
+}
+
+
+/*
+ * This function assumes that the text in cCol is an ASCII number. 0 is
+ * returned if it is not found.
+ */
+INT GetMCLBColValue(LPTSTR pszSearch, HWND hwndLBFrame, INT cCol)
+{
+ MCLBSTRUCT *pmclb;
+ LPTSTR psz;
+ INT lit;
+
+ pmclb = (MCLBSTRUCT *)GetWindowLong(hwndLBFrame, 0);
+
+ lit = (INT)SendMessage(pmclb->hwndLB, LB_FINDSTRING, (WPARAM)-1,
+ (LPARAM)(LPTSTR)pszSearch);
+ if (lit < 0) {
+ return(0);
+ }
+ psz = (LPTSTR)SendMessage(pmclb->hwndLB, LB_GETITEMDATA, lit, 0);
+ while (--cCol && (psz = wcschr(psz, '\t') + 1)) {
+ ;
+ }
+ if (psz) {
+ return(atoi(psz));
+ } else {
+ return(0);
+ }
+}
+
+
+
+/*
+ * Returns fFoundAndRemoved
+ */
+BOOL DeleteMCLBText(LPTSTR pszSearch, HWND hwndLBFrame)
+{
+ MCLBSTRUCT *pmclb;
+ INT lit;
+
+ pmclb = (MCLBSTRUCT *)GetWindowLong(hwndLBFrame, 0);
+ lit = (INT)SendMessage(pmclb->hwndLB, LB_FINDSTRING, (WPARAM)-1,
+ (LONG)(LPTSTR)pszSearch);
+ if (lit >= 0) {
+ SendMessage(pmclb->hwndLB, LB_DELETESTRING, lit, 0);
+ return(TRUE);
+ }
+ return(FALSE);
+}
+
+
+/*
+ * Returns >0 if item1 comes first, <0 if item2 comes first, 0 if ==.
+ */
+INT CompareItems(LPTSTR psz1, LPTSTR psz2, INT SortCol, INT cCols)
+{
+ INT i, Col;
+
+ i = CmpCols(psz1, psz2, SortCol);
+ if (i != 0) {
+ return(i);
+ }
+ for (Col = 0; Col < cCols; Col++) {
+ if (Col == SortCol) {
+ continue;
+ }
+ i = CmpCols(psz1, psz2, Col);
+ if (i != 0) {
+ return(i);
+ }
+ }
+ return(0);
+}
+
+
+INT CmpCols(LPTSTR psz1, LPTSTR psz2, INT SortCol)
+{
+ LPTSTR psz, pszT1, pszT2;
+ INT iRet;
+
+ while (SortCol--) {
+ psz = wcschr(psz1, '\t');
+ if (psz != NULL) {
+ psz1 = psz + 1;
+ } else {
+ psz1 = psz1 + lstrlen(psz1);
+ }
+ psz = wcschr(psz2, '\t');
+ if (psz != NULL) {
+ psz2 = psz + 1;
+ } else {
+ psz2 = psz2 + lstrlen(psz2);
+ }
+ }
+ pszT1 = wcschr(psz1, '\t');
+ pszT2 = wcschr(psz2, '\t');
+
+ if (pszT1) {
+ *pszT1 = '\0';
+ }
+ if (pszT2) {
+ *pszT2 = '\0';
+ }
+
+ if (!lstrcmp((LPCTSTR)RefString(IDS_WILD), psz1)
+ || !lstrcmp((LPCTSTR) RefString(IDS_WILD), psz2)) {
+ iRet = 0;
+ } else {
+ iRet = lstrcmp(psz1, psz2);
+ }
+
+ if (pszT1) {
+ *pszT1 = '\t';
+ }
+ if (pszT2) {
+ *pszT2 = '\t';
+ }
+
+ return(iRet);
+}
+
+
+
+VOID DrawLBItem(LPDRAWITEMSTRUCT lpdis)
+{
+ RECT rcDraw;
+ INT cxSection;
+ LPTSTR psz, pszEnd;
+
+ if (!lpdis->itemData)
+ return;
+ if ((lpdis->itemAction & ODA_DRAWENTIRE) ||
+ ((lpdis->itemAction & ODA_SELECT) &&
+ (lpdis->itemState & ODS_SELECTED))) {
+ rcDraw = lpdis->rcItem;
+ if (lpdis->CtlType != ODT_BUTTON) { // hack to avoid erasure
+ HBRUSH hbr;
+
+ hbr = CreateSolidBrush(GetSysColor(COLOR_WINDOW));
+ FillRect(lpdis->hDC, &lpdis->rcItem, hbr);
+ DeleteObject(hbr);
+ }
+ cxSection = (rcDraw.right - rcDraw.left) / lpdis->CtlID;
+ psz = (LPTSTR)(UINT)lpdis->itemData;
+ rcDraw.right = rcDraw.left + cxSection;
+ while (pszEnd = wcschr(psz, '\t')) {
+ *pszEnd = '\0';
+ DrawText(lpdis->hDC, psz, -1, &rcDraw, DT_LEFT);
+ OffsetRect(&rcDraw, cxSection, 0);
+ *pszEnd = '\t';
+ psz = pszEnd + 1;
+ }
+ DrawText(lpdis->hDC, psz, -1, &rcDraw, DT_LEFT);
+
+ if (lpdis->itemState & ODS_SELECTED)
+ InvertRect(lpdis->hDC, &lpdis->rcItem);
+
+ if (lpdis->itemState & ODS_FOCUS)
+ DrawFocusRect(lpdis->hDC, &lpdis->rcItem);
+
+ } else if (lpdis->itemAction & ODA_SELECT) {
+
+ InvertRect(lpdis->hDC, &lpdis->rcItem);
+
+ } else if (lpdis->itemAction & ODA_FOCUS) {
+
+ DrawFocusRect(lpdis->hDC, &lpdis->rcItem);
+
+ }
+}
+
+
diff --git a/private/sdktools/ddespy/lists.h b/private/sdktools/ddespy/lists.h
new file mode 100644
index 000000000..66cd31236
--- /dev/null
+++ b/private/sdktools/ddespy/lists.h
@@ -0,0 +1,35 @@
+/*
+ * LISTS.H
+ *
+ * Header file for multi-column listbox module.
+ */
+
+typedef struct {
+ LPTSTR lpszHeadings;
+} MCLBCREATESTRUCT;
+
+
+typedef struct {
+ HWND hwndLB;
+ LPTSTR pszHeadings;
+ INT cCols;
+ INT SortCol;
+} MCLBSTRUCT;
+
+#define MYLBSTYLE WS_CHILD|WS_BORDER |LBS_SORT| \
+ WS_VSCROLL|LBS_OWNERDRAWFIXED|LBS_NOINTEGRALHEIGHT
+
+HWND CreateMCLBFrame(
+ HWND hwndParent,
+ LPTSTR lpszTitle, /* frame title string */
+ UINT dwStyle, /* frame styles */
+ HICON hIcon, /* icon */
+ HBRUSH hbrBkgnd, /* background for heading.*/
+ LPTSTR lpszHeadings); /* tab delimited list of headings. */
+ /* The number of headings indicate */
+ /* the number of collumns. */
+
+VOID AddMCLBText(LPTSTR pszSearch, LPTSTR pszReplace, HWND hwndLBFrame);
+INT GetMCLBColValue(LPTSTR pszSearch, HWND hwndLBFrame, int cCol);
+BOOL DeleteMCLBText(LPTSTR pszSearch, HWND hwndLBFrame);
+
diff --git a/private/sdktools/ddespy/makefile b/private/sdktools/ddespy/makefile
new file mode 100644
index 000000000..6ee4f43fa
--- /dev/null
+++ b/private/sdktools/ddespy/makefile
@@ -0,0 +1,6 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/sdktools/ddespy/sources b/private/sdktools/ddespy/sources
new file mode 100644
index 000000000..d38b8f24f
--- /dev/null
+++ b/private/sdktools/ddespy/sources
@@ -0,0 +1,20 @@
+MAJORCOMP=shell
+MINORCOMP=ddespy
+
+TARGETNAME=ddespy
+TARGETPATH=obj
+TARGETTYPE=LIBRARY
+TARGETLIBS=
+
+SOURCES=ddespy.c \
+ lists.c \
+ testsubs.c \
+ ddespy.rc
+
+C_DEFINES= -DWIN32
+
+UMTYPE=windows
+UMAPPL=ddespy
+UMENTRY=winmain
+UMLIBS=obj\*\ddespy.res \
+ obj\*\ddespy.lib
diff --git a/private/sdktools/ddespy/testsubs.c b/private/sdktools/ddespy/testsubs.c
new file mode 100644
index 000000000..ed03c20fc
--- /dev/null
+++ b/private/sdktools/ddespy/testsubs.c
@@ -0,0 +1,344 @@
+/*
+ * TESTSUBS.C
+ *
+ * String formatting class, window procedure and helper functions
+ */
+
+#define UNICODE
+#include <windows.h>
+#include <windowsx.h>
+#include <stdio.h>
+#include <string.h>
+#include "ddespy.h"
+#include "globals.h"
+
+#define OFF2P(psw, off) ((TCHAR *)psw + off)
+#define BOUND(n, min, max) ((n) < (min) ? (min) : ((n) > (max) ? (max) : n))
+
+INT cyChar; /* Height of a line */
+INT cxChar;
+INT cyDescent;
+
+
+/***************************** Public Function ****************************\
+* BOOL InitTestSubs( )
+*
+* This routine MUST be called before using anything in this file. Registers
+* window classes, loads brushes, etc. Returns TRUE if successful, FALSE
+* otherwise.
+*
+\***************************************************************************/
+
+BOOL InitTestSubs()
+{
+ WNDCLASS cls;
+
+ cls.style = 0;
+ cls.lpfnWndProc = (WNDPROC)StrWndProc;
+ cls.cbClsExtra = 0;
+ cls.cbWndExtra = sizeof(HANDLE);
+ cls.hInstance = hInst;
+ cls.hIcon = NULL;
+ cls.hCursor = LoadCursor(NULL, IDC_ARROW);
+ cls.hbrBackground = (HBRUSH)COLOR_WINDOW;
+ cls.lpszMenuName = NULL;
+ cls.lpszClassName = (LPCTSTR) RefString(IDS_STRINGCLASS);
+
+ if (!RegisterClass((WNDCLASS FAR * ) & cls))
+ return(FALSE);
+
+ return(TRUE);
+}
+
+
+VOID CloseTestSubs(
+HANDLE hInst)
+{
+ UnregisterClass((LPCTSTR) RefString(IDS_STRINGCLASS), hInst);
+}
+
+
+
+VOID NextLine( STRWND *psw)
+{
+ psw->offBottomLine += psw->cchLine;
+ if (psw->offBottomLine == psw->offBufferMax)
+ psw->offBottomLine = psw->offBuffer;
+ psw->offOutput = psw->offBottomLine;
+ *OFF2P(psw, psw->offOutput) = TEXT('\0');
+}
+
+
+/***************************** Public Function ****************************\
+* VOID DrawString(hwnd, sz)
+*
+* This routine prints a string in the specified StringWindow class window.
+* sz is a NEAR pointer to a zero-terminated string, which can be produced
+* with wsprintf().
+\***************************************************************************/
+
+VOID DrawString( HWND hwnd, TCHAR *sz)
+{
+ register STRWND *psw;
+ INT cLines = 1;
+ HANDLE hpsw;
+
+ hpsw = (HANDLE)GetWindowLong(hwnd, 0);
+ psw = (STRWND *)LocalLock(hpsw);
+
+ NextLine(psw);
+ while (*sz) {
+ switch (*sz) {
+ case TEXT('\r'):
+ break;
+
+ case TEXT('\n'):
+ *OFF2P(psw, psw->offOutput++) = TEXT('\0');
+ NextLine(psw);
+ cLines++;
+ break;
+
+ default:
+ *OFF2P(psw, psw->offOutput++) = *sz;
+ }
+ sz++;
+ }
+ *OFF2P(psw, psw->offOutput++) = TEXT('\0');
+ LocalUnlock(hpsw);
+
+ ScrollWindow(hwnd, 0, -((cyChar + cyDescent) * cLines), (LPRECT)NULL,
+ (LPRECT)NULL);
+ UpdateWindow(hwnd);
+}
+
+/***************************** Public Function ****************************\
+* "StringWindow" window class
+*
+* Windows of the "StringWindow" window class are simple scrolling text output
+* windows that are refreshed properly as windows are rearranged. A text buffer
+* is maintained to store the characters as they are drawn.
+*
+* When creating a StringWindow window, lpCreateParams is actually a UINT
+* containing the dimensions of the text buffer to be created, if 0L, then
+* a 80 by 25 buffer is created.
+*
+\***************************************************************************/
+
+LONG CALLBACK StrWndProc(HWND hwnd, UINT msg, WPARAM wParam, UINT lParam)
+{
+ HANDLE hpsw;
+ PAINTSTRUCT ps;
+ RECT rc;
+
+ switch (msg) {
+ case WM_CREATE:
+ cyChar = 14;
+ cxChar = 8;
+ cyDescent = 2;
+ if (*(PUINT)lParam == 0L) {
+ *(PUINT)lParam = MAKELONG(80, 50);
+ }
+ if (!StrWndCreate(hwnd, LOWORD(*(PUINT)lParam), HIWORD(*(PUINT)lParam)))
+ return(TRUE);
+ break;
+
+ case WM_SIZE:
+ InvalidateRect(hwnd, NULL, TRUE);
+ break;
+
+ case WM_DESTROY:
+ if ((hpsw = (HANDLE)GetWindowLong(hwnd, 0)) != NULL)
+ LocalFree(hpsw);
+ break;
+
+ case WM_ERASEBKGND:
+ GetClientRect(hwnd, (LPRECT) &rc);
+ FillRect((HDC) wParam, (LPRECT) &rc, GetStockObject(WHITE_BRUSH));
+ break;
+
+ case WM_VSCROLL:
+ scroll(hwnd, GET_WM_VSCROLL_CODE(wParam, lParam),
+ GET_WM_VSCROLL_POS(wParam, lParam), SB_VERT);
+ break;
+
+ case WM_HSCROLL:
+ scroll(hwnd, GET_WM_HSCROLL_CODE(wParam, lParam),
+ GET_WM_HSCROLL_POS(wParam, lParam), SB_HORZ);
+ break;
+
+ case WM_PAINT:
+ BeginPaint(hwnd, &ps);
+ PaintStrWnd(hwnd, &ps);
+ EndPaint(hwnd, &ps);
+ break;
+
+ default:
+ return(DefWindowProc(hwnd, msg, wParam, lParam));
+ break;
+ }
+ return(0L);
+}
+
+
+
+VOID scroll(HWND hwnd, UINT msg, UINT sliderpos, UINT style)
+{
+ RECT rc;
+ INT iPos;
+ INT dn;
+ HANDLE hpsw;
+ register STRWND *psw;
+
+ GetClientRect(hwnd, (LPRECT) &rc);
+ iPos = GetScrollPos(hwnd, style);
+ hpsw = (HANDLE)GetWindowLong(hwnd, 0);
+ psw = (STRWND *)LocalLock(hpsw);
+
+ switch (msg) {
+ case SB_LINEDOWN:
+ dn = 1;
+ break;
+
+ case SB_LINEUP:
+ dn = -1;
+ break;
+
+ case SB_PAGEDOWN:
+ if (style == SB_VERT) {
+ dn = rc.bottom / (cyChar + cyDescent);
+ } else {
+ dn = rc.right / cxChar;
+ }
+ break;
+
+ case SB_PAGEUP:
+ if (style == SB_VERT) {
+ dn = -rc.bottom / (cyChar + cyDescent);
+ } else {
+ dn = -rc.right / cxChar;
+ }
+ break;
+
+ case SB_THUMBTRACK:
+ case SB_THUMBPOSITION:
+ dn = sliderpos-iPos;
+ break;
+
+ default:
+ dn = 0;
+ }
+ if (style == SB_VERT) {
+ if (dn = BOUND (iPos + dn, 0, psw->cLine) - iPos) {
+ psw->cBottomLine -= dn;
+ ScrollWindow (hwnd, 0, -dn * (cyChar + cyDescent), NULL, NULL);
+ SetScrollPos (hwnd, SB_VERT, iPos + dn, TRUE);
+ }
+ } else /* style == SB_HORZ */ {
+ if (dn = BOUND (iPos + dn, 0, psw->cchLine) - iPos) {
+ psw->cLeftChar += dn;
+ ScrollWindow (hwnd, -dn * cxChar, 0, NULL, NULL);
+ SetScrollPos (hwnd, SB_HORZ, iPos + dn, TRUE);
+ }
+ }
+ LocalUnlock(hpsw);
+}
+
+
+
+BOOL StrWndCreate(HWND hwnd, INT cchLine, INT cLine)
+{
+ register INT off;
+ STRWND *psw;
+ HANDLE hpsw;
+
+ if ((hpsw = LocalAlloc(LMEM_MOVEABLE, sizeof(STRWND)
+ + (sizeof (TCHAR) * cchLine * cLine))) == NULL)
+ return(FALSE);
+ SetWindowLong(hwnd, 0, (UINT)hpsw);
+
+
+ psw = (STRWND *)LocalLock(hpsw);
+ psw->cchLine = cchLine;
+ psw->cLine = cLine;
+ off = sizeof(STRWND);
+ psw->offBuffer = off;
+ psw->offBufferMax = off + cchLine * cLine;
+ psw->offBottomLine = off;
+ psw->offOutput = off;
+ psw->cBottomLine = 0;
+ psw->cLeftChar = 0;
+
+ ClearScreen(psw);
+
+ SetScrollRange(hwnd, SB_VERT, 0, cLine, FALSE);
+ SetScrollPos(hwnd, SB_VERT, cLine, TRUE);
+ SetScrollRange(hwnd, SB_HORZ, 0, cchLine, TRUE);
+ LocalUnlock(hpsw);
+ return(TRUE);
+}
+
+
+VOID ClearScreen(register STRWND *psw)
+{
+ register INT off;
+ /*
+ * Make all the lines empty
+ */
+ off = psw->offBuffer;
+ while (off < psw->offBufferMax) {
+ *OFF2P(psw, off) = TEXT('\0');
+ off += psw->cchLine;
+ }
+}
+
+
+
+
+VOID PaintStrWnd( HWND hwnd, LPPAINTSTRUCT pps)
+{
+ register STRWND *psw;
+ register INT off;
+ INT x;
+ INT y;
+ RECT rc, rcOut;
+ HANDLE hpsw;
+
+
+ SelectObject(pps->hdc, GetStockObject(SYSTEM_FIXED_FONT));
+ hpsw = (HANDLE)GetWindowLong(hwnd, 0);
+ psw = (STRWND *)LocalLock(hpsw);
+
+ GetClientRect(hwnd, (LPRECT)&rc);
+ if (!pps->fErase)
+ FillRect(pps->hdc, (LPRECT)&rc, GetStockObject(WHITE_BRUSH));
+
+ x = rc.left - cxChar * psw->cLeftChar;
+ y = rc.bottom - cyDescent + (cyChar + cyDescent) * psw->cBottomLine;
+ off = psw->offBottomLine;
+
+ if (&pps->rcPaint != NULL)
+ IntersectRect((LPRECT)&rc, (LPRECT)&rc, &pps->rcPaint);
+
+ do {
+ if (y <= rc.top - cyDescent)
+ break;
+ if (y - cyChar <= rc.bottom) {
+ rcOut.left = x;
+ rcOut.bottom = y + cyDescent;
+ rcOut.right = 1000;
+ rcOut.top = y - cyChar;
+ DrawText(pps->hdc, (LPTSTR)OFF2P(psw, off), -1, (LPRECT)&rcOut,
+ DT_LEFT | DT_VCENTER | DT_NOCLIP | DT_EXPANDTABS |
+ DT_EXTERNALLEADING | DT_NOPREFIX | DT_TABSTOP | 0x0400);
+ }
+ y -= cyChar + cyDescent;
+ /*
+ * Back up to previous line
+ */
+ if (off == psw->offBuffer)
+ off = psw->offBufferMax;
+ off -= psw->cchLine;
+ } while (off != psw->offBottomLine);
+ LocalUnlock(hpsw);
+}
+