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.