counter.dpr
来自「一本已经绝版的好书」· DPR 代码 · 共 164 行
DPR
164 行
// Module name: Counter.c ->> Counter.dpr
// Notices: Copyright (c) 1996-1997 Jeffrey Richter
// Translator: 刘麻子, Liu_mazi@126.com
program Counter;
{$R 'Counter.res' 'Counter.rc'}
uses Windows, Messages, CmnHdr in '..\CmnHdr.pas', WindowsX in '..\WindowsX.pas';
const
IDD_COUNTER = 101;
IDI_COUNTER = 102;
IDC_FIBER = 1000;
IDC_ANSWER = 1001;
IDC_COUNT = 1002;
// 计算纤程状态
type
TBkgndProcState = (BPS_STARTOVER, BPS_CONTINUE, BPS_DONE);
type
PFiberInfo = ^TFiberInfo;
TFiberInfo = record
pFiberUI: Pointer; // 界面纤程环境块
hWnd: DWORD; // 界面对话框句柄
bps: TBkgndProcState; // 计算纤程状态
end;
// 纤程共享信息
var
g_FiberInfo: TFiberInfo;
// 计算纤程回调
procedure Counter_FiberFunc(var pFiberInfo: TFiberInfo); stdcall;
var
fTranslated: BOOL;
x, nCount: Integer;
begin
SetDlgItemText(pFiberInfo.hWnd, IDC_FIBER, 'Recalculation');
nCount := GetDlgItemInt(pFiberInfo.hWnd, IDC_COUNT, fTranslated, FALSE);
for x := 0 to nCount do
begin
// 有消息则切换到界面纤程
if (HIWORD(GetQueueStatus(QS_ALLEVENTS)) <> 0) then
begin
SwitchToFiber(pFiberInfo.pFiberUI);
SetDlgItemText(pFiberInfo.hWnd, IDC_FIBER, 'Recalculation');
end;
SetDlgItemInt(pFiberInfo.hWnd, IDC_ANSWER, x, FALSE);
Sleep(150);
end;
// 计算完毕, 切换到界面纤程
pFiberInfo.bps := BPS_DONE;
SwitchToFiber(pFiberInfo.pFiberUI);
end;
// WM_INITDIALOG
function Counter_OnInitDialog(hWnd, hWndFocus: HWND; lParam: LPARAM): BOOL;
begin
chSETDLGICONS(hWnd, IDI_COUNTER, IDI_COUNTER);
{$IfDef DEBUG}
SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOZORDER or SWP_NOSIZE);
{$EndIf}
SetDlgItemInt(hWnd, IDC_COUNT, 0, FALSE);
Result := TRUE;
end;
// WM_COMMAND
procedure Counter_OnCommand(hWnd: HWND; id: Integer; hWndCtl: HWND; codeNotify: UINT);
begin
case (id) of
IDCANCEL: DestroyWindow(hWnd); // 消息循环停止
IDC_COUNT: if (codeNotify = EN_CHANGE) then g_FiberInfo.bps := BPS_STARTOVER; // 重新计算
end;
end;
// 对话框回调
function Counter_DlgProc(hWnd: HWND; uMsg: UINT; wParam: WPARAM; lParam: LPARAM): BOOL; stdcall;
begin
case (uMsg) of
WM_INITDIALOG:
begin
Result := SetDlgMsgResult(hWnd, LRESULT(Counter_OnInitDialog(hWnd, wParam, lParam)));
end;
WM_COMMAND:
begin
Counter_OnCommand(hWnd, LOWORD(wParam), lParam, HIWORD(wParam));
Result := TRUE;
end;
else Result := FALSE;
end;
end;
// 程序入口
var
pFiberCounter: Pointer = nil;
msg: TMsg;
begin
chWARNIFUNICODEUNDERWIN95();
// 转换为纤程
g_FiberInfo.pFiberUI := Pointer(ConvertThreadToFiber(nil));
// 建立对话框
g_FiberInfo.hwnd := CreateDialog(HInstance, MakeIntResource(IDD_COUNTER), 0, @Counter_DlgProc);
SetDlgItemText(g_FiberInfo.hWnd, IDC_FIBER, 'User-interface');
g_FiberInfo.bps := BPS_DONE;
// 对话框存在
while IsWindow(g_FiberInfo.hWnd) do
begin
if PeekMessage(msg, 0, 0, 0, PM_REMOVE) then
begin
if (IsDialogMessage(g_FiberInfo.hWnd, msg) = FALSE) then
begin
TranslateMessage(msg);
DispatchMessage(msg);
end;
end else
begin
case (g_FiberInfo.bps) of
BPS_DONE: // 无须计算
begin
WaitMessage();
end;
BPS_STARTOVER: // 重头计算
begin
if (pFiberCounter <> nil) then
begin
DeleteFiber(pFiberCounter);
pFiberCounter := nil;
end;
pFiberCounter := Pointer(CreateFiber(0, @Counter_FiberFunc, @g_FiberInfo));
g_FiberInfo.bps := BPS_CONTINUE;
// goto BPS_CONTINUE;
end;
BPS_CONTINUE: // 继续计算
begin
SwitchToFiber(pFiberCounter);
SetDlgItemText(g_FiberInfo.hWnd, IDC_FIBER, 'User-interface');
if (g_FiberInfo.bps = BPS_DONE) then
begin
DeleteFiber(pFiberCounter);
pFiberCounter := nil;
end
end;
end; // END: case (g_FiberInfo.bps) of ...
end;
end; // END: while IsWindow(g_FiberInfo.hWnd) do ...
end.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?