Last updated: 15. 1.1998, 21:42
<*/NOWARN:F*>
MODULE ShowPop2;
(*------------------------------------------
SHOWPOP2.C --- DDEML Client using DDEPOP2
(c) Charles Petzold, 1996
ShowPop2.mod --- Translation to Stony Brook Modula-2
(c) Peter Stadler, 1998
------------------------------------------*)
IMPORT Helper;
IMPORT WINUSER;
IMPORT WINGDI;
IMPORT WIN32;
IMPORT WINX;
IMPORT SYSTEM;
IMPORT DDEML;
IMPORT h2d_showpop;
IMPORT Str;
CONST WM_USER_INITIATE = WINUSER.WM_USER + 1;
CONST DDE_TIMEOUT = 3000;
szAppName = "ShowPop2";
CONST
szService = "DdePop2";
szTopic = "US_Population";
VAR
cxChar : WIN32.LONG;
cyChar : WIN32.LONG;
VAR
idInst : WIN32.DWORD;
hConv : DDEML.HCONV;
hwnd : WIN32.HWND;
wc : WINUSER.WNDCLASSEX;
msg : WINUSER.MSG;
ok : BOOLEAN;
<*/PUSH*>
%IF WIN32 %THEN
<*/CALLS:WIN32SYSTEM*>
%ELSE
<*/CALLS:WINSYSTEM*>
%END
(*++++*****************************************************************)
PROCEDURE DdeCallback (iType : WIN32.UINT;
(**********************************************************************)
iFmt : WIN32.UINT;
hConv : DDEML.HCONV;
hsz1 : WIN32.WPARAM;
hsz2 : WIN32.WPARAM;
hData : WIN32.WPARAM;
dwData1 : WIN32.DWORD;
dwData2 : WIN32.DWORD) : DDEML.HDDEDATA [EXPORT];
VAR
szPopulation : ARRAY[0..15] OF CHAR;
szItem : ARRAY[0..15] OF CHAR;
i : INTEGER;
BEGIN
CASE (iType) OF
| DDEML.XTYP_ADVDATA : (* hsz1 := topic *)
(* hsz2 := item *)
(* hData := data *)
(* Check for matching format and data item *)
IF (iFmt # WINUSER.CF_TEXT) THEN
RETURN DDEML.DDE_FNOTPROCESSED;
END;
DDEML.DdeQueryString (idInst, hsz2, szItem, SIZE (szItem), 0);
i := 0;
LOOP
IF (Str.Compare(szItem, h2d_showpop.pop[i].szAbb^) = 0) THEN
EXIT;
END;
INC(i);
IF(i>=h2d_showpop.NUM_STATES) THEN
EXIT;
END;
END;
IF (i >= h2d_showpop.NUM_STATES) THEN
RETURN DDEML.DDE_FNOTPROCESSED;
END;
(* Store the data and invalidate the window *)
DDEML.DdeGetData (hData, SYSTEM.ADR(szPopulation),
SIZE (szPopulation), 0);
h2d_showpop.pop[i].lPop := Str.StrToInt(szPopulation,10,ok);
WINUSER.InvalidateRect (hwnd, WINX.NIL_RECT, FALSE);
RETURN SYSTEM.CAST(DDEML.HDDEDATA, DDEML.DDE_FACK);
| DDEML.XTYP_DISCONNECT :
hConv := 0;
WINUSER.MessageBox (hwnd, "The server has disconnected.",
szAppName, WINUSER.MB_ICONASTERISK BOR WINUSER.MB_OK);
RETURN 0;
ELSE
RETURN 0;
END;
END DdeCallback;
<*/POP*>
<*/PUSH*>
%IF WIN32 %THEN
<*/CALLS:WIN32SYSTEM*>
%ELSE
<*/CALLS:WINSYSTEM*>
%END
(*++++*****************************************************************)
PROCEDURE WndProc (hwnd : WIN32.HWND;
(**********************************************************************)
iMsg : WIN32.UINT;
wParam : WIN32.WPARAM;
lParam : WIN32.LPARAM) : WIN32.LRESULT [EXPORT];
VAR
hszItem : DDEML.HSZ;
hszService : DDEML.HSZ;
hszTopic : DDEML.HSZ;
i : INTEGER;
szBuffer : ARRAY[0..23] OF CHAR;
hdc : WIN32.HDC;
ps : WINUSER.PAINTSTRUCT;
x : WIN32.LONG;
y : WIN32.LONG;
tm : WINGDI.TEXTMETRIC;
BEGIN
CASE (iMsg) OF
| WINUSER.WM_CREATE :
hdc := WINUSER.GetDC (hwnd);
WINGDI.GetTextMetrics (hdc, tm);
cxChar := tm.tmAveCharWidth;
cyChar := tm.tmHeight + tm.tmExternalLeading;
WINUSER.ReleaseDC (hwnd, hdc);
RETURN 0;
| WM_USER_INITIATE :
(* Try connecting *)
hszService := DDEML.DdeCreateStringHandle (idInst, szService, 0);
hszTopic := DDEML.DdeCreateStringHandle (idInst, szTopic, 0);
hConv := DDEML.DdeConnect (idInst, hszService, hszTopic, NIL);
(* If that doesn't work, load server *)
IF (hConv = 0) THEN
WIN32.WinExec (szService, WINUSER.SW_SHOWMINNOACTIVE);
hConv := DDEML.DdeConnect (idInst, hszService, hszTopic, NIL);
END;
(* Free the string handles *)
DDEML.DdeFreeStringHandle (idInst, hszService);
DDEML.DdeFreeStringHandle (idInst, hszTopic);
(* If still not connected, display message box *)
IF (hConv = 0) THEN
WINUSER.MessageBox (hwnd, "Cannot connect with DDEPOP2.EXE!",
szAppName, WINUSER.MB_ICONEXCLAMATION BOR WINUSER.MB_OK);
RETURN 0;
END;
(* Request notification *)
FOR i := 0 TO h2d_showpop.NUM_STATES-1 DO
hszItem := DDEML.DdeCreateStringHandle (idInst, h2d_showpop.pop[i].szAbb^, 0);
DDEML.DdeClientTransaction (NIL, 0, hConv, hszItem, WINUSER.CF_TEXT,
DDEML.XTYP_ADVSTART BOR DDEML.XTYPF_ACKREQ,
DDE_TIMEOUT, WINX.NIL_DWORD);
DDEML.DdeFreeStringHandle (idInst, hszItem);
END;
IF (i < h2d_showpop.NUM_STATES) THEN
WINUSER.MessageBox (hwnd, "Failure on WM_DDE_ADVISE!",
szAppName, WINUSER.MB_ICONEXCLAMATION BOR WINUSER.MB_OK);
END;
RETURN 0;
| WINUSER.WM_PAINT :
hdc := WINUSER.BeginPaint (hwnd, ps);
FOR i := 0 TO h2d_showpop.NUM_STATES-1 DO
IF (i < (h2d_showpop.NUM_STATES + 1) DIV 2) THEN
x := cxChar;
y := i * cyChar;
ELSE
x := 44 * cxChar;
y := (i - (h2d_showpop.NUM_STATES + 1) DIV 2) * cyChar;
END;
WINGDI.TextOut (hdc, x, y, szBuffer,
WINUSER.wsprintf (szBuffer, "%-20s",
SYSTEM.CAST(WIN32.PSTR,h2d_showpop.pop[i].szState)));
x := x + 36 * cxChar;
WINGDI.SetTextAlign (hdc, WINGDI.TA_RIGHT BOR WINGDI.TA_TOP);
WINGDI.TextOut (hdc, x, y, szBuffer,
WINUSER.wsprintf (szBuffer, "%10ld", h2d_showpop.pop[i].lPop));
WINGDI.SetTextAlign (hdc, WINGDI.TA_LEFT BOR WINGDI.TA_TOP);
END;
WINUSER.EndPaint (hwnd, ps);
RETURN 0;
| WINUSER.WM_CLOSE :
IF (hConv # 0) THEN
(* Stop the advises *)
FOR i := 0 TO h2d_showpop.NUM_STATES-1 DO
hszItem := DDEML.DdeCreateStringHandle (idInst, h2d_showpop.pop[i].szAbb^, 0);
DDEML.DdeClientTransaction (NIL, 0, hConv, hszItem, WINUSER.CF_TEXT,
DDEML.XTYP_ADVSTOP, DDE_TIMEOUT, WINX.NIL_DWORD);
DDEML.DdeFreeStringHandle (idInst, hszItem);
END;
(* Disconnect the conversation *)
DDEML.DdeDisconnect (hConv);
END;
(* for default processing DO *)
| WINUSER.WM_DESTROY :
WINUSER.PostQuitMessage (0);
RETURN 0;
ELSE
RETURN WINUSER.DefWindowProc (hwnd, iMsg, wParam, lParam);
END;
END WndProc;
<*/POP*>
(*++++*****************************************************************)
PROCEDURE InitApplication () : BOOLEAN;
(**********************************************************************)
VAR
rc : CARDINAL;
BEGIN
wc.cbSize := SIZE(wc);
wc.style := WINUSER.CS_HREDRAW BOR WINUSER.CS_VREDRAW;
wc.style := 0;
wc.lpfnWndProc := WndProc;
wc.cbClsExtra := 0;
wc.cbWndExtra := 0;
wc.hInstance := WINX.Instance;
wc.hIcon := WINUSER.LoadIcon (WINX.Instance,szAppName);
wc.hCursor := WINUSER.LoadCursor (NIL, WINUSER.IDC_ARROW^);
wc.hbrBackground := SYSTEM.CAST(WIN32.HBRUSH, WINGDI.GetStockObject (WINGDI.WHITE_BRUSH));
wc.lpszMenuName := NIL;
wc.lpszClassName := SYSTEM.ADR(szAppName);
wc.hIconSm := WINUSER.LoadIcon (WINX.Instance,szAppName);
rc := WINUSER.RegisterClassEx(wc);
RETURN rc#0;
END InitApplication;
(*++++*****************************************************************)
PROCEDURE InitMainWindow () : BOOLEAN;
(**********************************************************************)
BEGIN
hwnd := WINUSER.CreateWindow (szAppName,
"DDEML Client - US Population: Translation to Stony Brook Modula-2",
WINUSER.WS_OVERLAPPEDWINDOW,
WINUSER.CW_USEDEFAULT,
WINUSER.CW_USEDEFAULT,
WINUSER.CW_USEDEFAULT,
WINUSER.CW_USEDEFAULT,
NIL,
NIL,
WINX.Instance,
NIL);
WINUSER.ShowWindow (hwnd, WINUSER.SW_SHOWMINNOACTIVE);
WINUSER.UpdateWindow (hwnd);
(* Initialize for using DDEML *)
IF (DDEML.DdeInitialize (idInst, SYSTEM.CAST(DDEML.PFNCALLBACK,SYSTEM.ADR(DdeCallback)),
DDEML.APPCLASS_STANDARD BOR DDEML.APPCMD_CLIENTONLY, 0h)=1) THEN
WINUSER.MessageBox (hwnd, "Could not initialize server!",
szAppName, WINUSER.MB_ICONEXCLAMATION BOR WINUSER.MB_OK);
WINUSER.DestroyWindow (hwnd);
RETURN FALSE;
END;
(* Start things going *)
WINUSER.SendMessage (hwnd, WM_USER_INITIATE, 0, 0h);
END InitMainWindow;
BEGIN
IF InitApplication() AND InitMainWindow() THEN
WHILE (WINUSER.GetMessage(msg,NIL,0,0)) DO
WINUSER.TranslateMessage(msg);
WINUSER.DispatchMessage(msg);
END;
(* Uninitialize DDEML *)
DDEML.DdeUninitialize (idInst);
END;
END ShowPop2.