📄 showpop1.c
字号:
/*-----------------------------------------
SHOWPOP1.C -- DDE Client using DDEPOP1
(c) Charles Petzold, 1996
-----------------------------------------*/
#include <windows.h>
#include <dde.h>
#include <stdlib.h>
#include <string.h>
#include "showpop.h"
#define WM_USER_INITIATE (WM_USER + 1)
#define DDE_TIMEOUT 3000
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
char szAppName[] = "ShowPop1" ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
HWND hwnd ;
MSG msg ;
WNDCLASSEX wndclass ;
wndclass.cbSize = sizeof (wndclass) ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (hInstance, szAppName) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
wndclass.hIconSm = LoadIcon (hInstance, szAppName) ;
RegisterClassEx (&wndclass) ;
hwnd = CreateWindow (szAppName, "DDE Client - US Population",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd, iCmdShow) ;
UpdateWindow (hwnd) ;
SendMessage (hwnd, WM_USER_INITIATE, 0, 0L) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static BOOL fDoingInitiate = TRUE ;
static char szServerApp[] = "DdePop1",
szTopic[] = "US_Population" ;
static HWND hwndServer = NULL ;
static long cxChar, cyChar ;
ATOM aApp, aTop, aItem ;
char szBuffer[24], szPopulation[16], szItem[16] ;
DDEACK DdeAck ;
DDEDATA *pDdeData ;
DDEADVISE *pDdeAdvise ;
DWORD dwTime ;
GLOBALHANDLE hDdeAdvise, hDdeData ;
HDC hdc ;
MSG msg ;
PAINTSTRUCT ps ;
short i ;
long x, y ;
TEXTMETRIC tm ;
WORD wStatus ;
UINT uiLow, uiHi ;
switch (iMsg)
{
case WM_CREATE :
hdc = GetDC (hwnd) ;
GetTextMetrics (hdc, &tm) ;
cxChar = tm.tmAveCharWidth ;
cyChar = tm.tmHeight + tm.tmExternalLeading ;
ReleaseDC (hwnd, hdc) ;
return 0 ;
case WM_USER_INITIATE :
// Broadcast WM_DDE_INITIATE iMsg
aApp = GlobalAddAtom (szServerApp) ;
aTop = GlobalAddAtom (szTopic) ;
SendMessage (HWND_BROADCAST, WM_DDE_INITIATE, (WPARAM) hwnd,
MAKELONG (aApp, aTop)) ;
// If no response, try loading DDEPOP first
if (hwndServer == NULL)
{
WinExec (szServerApp, SW_SHOWMINNOACTIVE) ;
SendMessage (HWND_BROADCAST, WM_DDE_INITIATE, (WPARAM) hwnd,
MAKELONG (aApp, aTop)) ;
}
// Delete the atoms
GlobalDeleteAtom (aApp) ;
GlobalDeleteAtom (aTop) ;
fDoingInitiate = FALSE ;
// If still no response, display message box
if (hwndServer == NULL)
{
MessageBox (hwnd, "Cannot connect with DDEPOP1.EXE!",
szAppName, MB_ICONEXCLAMATION | MB_OK) ;
return 0 ;
}
// Post WM_DDE_ADVISE iMsgs
for (i = 0 ; i < NUM_STATES ; i++)
{
hDdeAdvise = GlobalAlloc (GHND | GMEM_DDESHARE,
sizeof (DDEADVISE)) ;
pDdeAdvise = (DDEADVISE *) GlobalLock (hDdeAdvise) ;
pDdeAdvise->fAckReq = TRUE ;
pDdeAdvise->fDeferUpd = FALSE ;
pDdeAdvise->cfFormat = CF_TEXT ;
GlobalUnlock (hDdeAdvise) ;
aItem = GlobalAddAtom (pop[i].szAbb) ;
if (!PostMessage (hwndServer, WM_DDE_ADVISE, (WPARAM) hwnd,
PackDDElParam (WM_DDE_ADVISE,
(UINT) hDdeAdvise, aItem)))
{
GlobalFree (hDdeAdvise) ;
GlobalDeleteAtom (aItem) ;
break ;
}
DdeAck.fAck = FALSE ;
dwTime = GetCurrentTime () ;
while (GetCurrentTime () - dwTime < DDE_TIMEOUT)
{
if (PeekMessage (&msg, hwnd, WM_DDE_ACK,
WM_DDE_ACK, PM_REMOVE))
{
GlobalDeleteAtom (HIWORD (msg.lParam)) ;
wStatus = LOWORD (msg.lParam) ;
DdeAck = *((DDEACK *) &wStatus) ;
if (DdeAck.fAck == FALSE)
GlobalFree (hDdeAdvise) ;
break ;
}
}
if (DdeAck.fAck == FALSE)
break ;
while (PeekMessage (&msg, hwnd, WM_DDE_FIRST,
WM_DDE_LAST, PM_REMOVE))
{
DispatchMessage (&msg) ;
}
}
if (i < NUM_STATES)
{
MessageBox (hwnd, "Failure on WM_DDE_ADVISE!",
szAppName, MB_ICONEXCLAMATION | MB_OK) ;
}
return 0 ;
case WM_DDE_ACK :
// In response to WM_DDE_INITIATE, save server window
if (fDoingInitiate)
{
UnpackDDElParam (WM_DDE_ACK, lParam, &uiLow, &uiHi) ;
FreeDDElParam (WM_DDE_ACK, lParam) ;
hwndServer = (HWND) wParam ;
GlobalDeleteAtom ((ATOM) uiLow) ;
GlobalDeleteAtom ((ATOM) uiHi) ;
}
return 0 ;
case WM_DDE_DATA :
// wParam -- sending window handle
// lParam -- DDEDATA memory handle & item atom
UnpackDDElParam (WM_DDE_DATA, lParam, &uiLow, &uiHi) ;
FreeDDElParam (WM_DDE_DATA, lParam) ;
hDdeData = (GLOBALHANDLE) uiLow ;
pDdeData = (DDEDATA *) GlobalLock (hDdeData) ;
aItem = (ATOM) uiHi ;
// Initialize DdeAck structure
DdeAck.bAppReturnCode = 0 ;
DdeAck.reserved = 0 ;
DdeAck.fBusy = FALSE ;
DdeAck.fAck = FALSE ;
// Check for matching format and data item
if (pDdeData->cfFormat == CF_TEXT)
{
GlobalGetAtomName (aItem, szItem, sizeof (szItem)) ;
for (i = 0 ; i < NUM_STATES ; i++)
if (strcmp (szItem, pop[i].szAbb) == 0)
break ;
if (i < NUM_STATES)
{
strcpy (szPopulation, (char *) pDdeData->Value) ;
pop[i].lPop = atol (szPopulation) ;
InvalidateRect (hwnd, NULL, FALSE) ;
DdeAck.fAck = TRUE ;
}
}
// Acknowledge if necessary
if (pDdeData->fAckReq == TRUE)
{
wStatus = *((WORD *) &DdeAck) ;
if (!PostMessage ((HWND) wParam, WM_DDE_ACK, (WPARAM) hwnd,
PackDDElParam (WM_DDE_ACK,
wStatus, aItem)))
{
GlobalDeleteAtom (aItem) ;
GlobalUnlock (hDdeData) ;
GlobalFree (hDdeData) ;
return 0 ;
}
}
else
{
GlobalDeleteAtom (aItem) ;
}
// Clean up
if (pDdeData->fRelease == TRUE || DdeAck.fAck == FALSE)
{
GlobalUnlock (hDdeData) ;
GlobalFree (hDdeData) ;
}
else
{
GlobalUnlock (hDdeData) ;
}
return 0 ;
case WM_PAINT :
hdc = BeginPaint (hwnd, &ps) ;
for (i = 0 ; i < NUM_STATES ; i++)
{
if (i < (NUM_STATES + 1) / 2)
{
x = cxChar ;
y = i * cyChar ;
}
else
{
x = 44 * cxChar ;
y = (i - (NUM_STATES + 1) / 2) * cyChar ;
}
TextOut (hdc, x, y, szBuffer,
wsprintf (szBuffer, "%-20s",
(PSTR) pop[i].szState)) ;
x += 36 * cxChar ;
SetTextAlign (hdc, TA_RIGHT | TA_TOP) ;
TextOut (hdc, x, y, szBuffer,
wsprintf (szBuffer, "%10ld", pop[i].lPop)) ;
SetTextAlign (hdc, TA_LEFT | TA_TOP) ;
}
EndPaint (hwnd, &ps) ;
return 0 ;
case WM_DDE_TERMINATE :
// Respond with another WM_DDE_TERMINATE iMsg
PostMessage (hwndServer, WM_DDE_TERMINATE, (WPARAM) hwnd, 0L) ;
hwndServer = NULL ;
return 0 ;
case WM_CLOSE :
if (hwndServer == NULL)
break ;
// Post WM_DDE_UNADVISE iMsg
PostMessage (hwndServer, WM_DDE_UNADVISE, (WPARAM) hwnd,
MAKELONG (CF_TEXT, NULL)) ;
dwTime = GetCurrentTime () ;
while (GetCurrentTime () - dwTime < DDE_TIMEOUT)
{
if (PeekMessage (&msg, hwnd, WM_DDE_ACK,
WM_DDE_ACK, PM_REMOVE))
break ;
}
// Post WM_DDE_TERMINATE iMsg
PostMessage (hwndServer, WM_DDE_TERMINATE, (WPARAM) hwnd, 0L) ;
dwTime = GetCurrentTime () ;
while (GetCurrentTime () - dwTime < DDE_TIMEOUT)
{
if (PeekMessage (&msg, hwnd, WM_DDE_TERMINATE,
WM_DDE_TERMINATE, PM_REMOVE))
break ;
}
break ; // for default processing
case WM_DESTROY :
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -