[分享]基于内核对象WaitableTimer实现的Timer组件

chenzhuo 2011-08-21 10:30:59
加精
把TTimer组件的代码抄了过来,把实现计数部分改由内核对象来实现。



unit WaitTimerU;

interface

uses
Classes, Windows, Consts;

type
TWaitTimer = class(TComponent)
private
FWaitableTimer: THandle;
FInterval: Cardinal;
FOnTimer: TNotifyEvent;
FEnabled: Boolean;
procedure UpdateTimer;
procedure SetEnabled(Value: Boolean);
procedure SetInterval(Value: Cardinal);
procedure SetOnTimer(Value: TNotifyEvent);
protected
procedure Timer; dynamic;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Enabled: Boolean read FEnabled write SetEnabled default True;
property Interval: Cardinal read FInterval write SetInterval default 1000;
property OnTimer: TNotifyEvent read FOnTimer write SetOnTimer;
end;

implementation

procedure TimerAPCProc(lpArgToCompletionRoutine: Pointer; dwTimerLowValue: DWORD;
dwTimerHighValue: DWORD); stdcall;
begin
TWaitTimer(lpArgToCompletionRoutine).Timer;
SleepEx(INFINITE, True);
end;

function WaitTimerThreadFun(P: Pointer): Integer; stdcall;
var
DueTime: Int64;
begin
with TWaitTimer(P) do
begin
DueTime := -Int64(Interval)*10000;
if SetWaitableTimer(FWaitableTimer, DueTime, Interval, @TimerAPCProc, P, False) then
begin
SleepEx(INFINITE, True);
end
else
raise EOutOfResources.Create(SNoTimers);
end;
Result := 0;
end;

{ TWaitTimer }

constructor TWaitTimer.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FEnabled := True;
FInterval := 1000;
FWaitableTimer := CreateWaitableTimer(nil, False, nil);
end;

destructor TWaitTimer.Destroy;
begin
FEnabled := False;
UpdateTimer;
CloseHandle(FWaitableTimer);
inherited;
end;

procedure TWaitTimer.SetEnabled(Value: Boolean);
begin
if Value <> FEnabled then
begin
FEnabled := Value;
UpdateTimer;
end;
end;

procedure TWaitTimer.SetInterval(Value: Cardinal);
begin
if Value <> FInterval then
begin
FInterval := Value;
UpdateTimer;
end;
end;

procedure TWaitTimer.SetOnTimer(Value: TNotifyEvent);
begin
FOnTimer := Value;
UpdateTimer;
end;

procedure TWaitTimer.Timer;
begin
if Assigned(FOnTimer) then FOnTimer(Self);
end;

procedure TWaitTimer.UpdateTimer;
var
ID: DWORD;
begin
CancelWaitableTimer(FWaitableTimer);
if (FInterval <> 0) and FEnabled and Assigned(FOnTimer) then
begin
CreateThread(nil, 0, @WaitTimerThreadFun, Self, 0, ID);
end;
end;

end.

...全文
1489 44 打赏 收藏 转发到动态 举报
写回复
用AI写文章
44 条回复
切换为时间正序
请发表友善的回复…
发表回复
msdtx 2012-03-14
  • 打赏
  • 举报
回复
这个回调不是 APC 的,和 CreateTimerQueueTimer 一样是在新线程中运行的。
yushf 2011-09-13
  • 打赏
  • 举报
回复
[Quote=引用 36 楼 yushf 的回复:]

想到一种更简洁的,可以把Timer也省掉了

RegisterWaitForSingleObject(FWaitObject, GetCurrentProcress(), @TimerAPCProc, Self, FInterval, 0);
[/Quote]

不能删帖,郁闷!收回上面的帖子!!!
yushf 2011-09-13
  • 打赏
  • 举报
回复
想到一种更简洁的,可以把Timer也省掉了

RegisterWaitForSingleObject(FWaitObject, GetCurrentProcress(), @TimerAPCProc, Self, FInterval, 0);
fsk_wyf 2011-09-13
  • 打赏
  • 举报
回复
34 g_stLedBlink[LED_RUN] 341 g_stLedBlink[LED_ALARM] 342
if(ucLedNum > LED_RUN){ return 11;}
if(341.wOntime == 342.wOntime \
&& 341.wPeriod == 342.wPeriod){
if(LED_ALARM == ucLedNum && CCU_TRUE == 341.ucEnable){342.wCnt = 341.wCnt;}
if(LED_RUN == ucLedNum && CCU_TRUE == 342.ucEnable){341.wCnt = 342.wCnt;}}221;
35 ADP_GPIO_Write(wGpioNum 351 if(CCU_OK == ADP_GPIO_OUTPUT_Read(wGpioNum, &tmp)) 352
UINT16 wGpioNum = 0; UINT32 324;UINT32 tmp = CCU_NULL_LONG;

/*CPU只控制run和alarm灯*/if(ucLedNum > LED_RUN){return 11;}
wGpioNum = (LED_ALARM == ucLedNum) ? GPIO_LED_ALARM:GPIO_LED_RUN;
switch(ucLedCtrl)
{
case LED_ON:
/*防止写重复,同时解决重复关闭ALM灯引起的闪亮的问题*/
352{if((UINT8)tmp == 0){221;}}ulRet = 351, 0);..;.. LED_OFF:
/*同上*/352{if((UINT8)tmp == 1){221;}}ulRet = 351, 1);..;.. LED_BLINK:
/*最小时间刻度为100ms*/wBlinkOnTime /= 100;wBlinkPeriod /= 100;
CHECK_LED_BLINK_PARA();g_stLedBlink[ucLedNum].wOntime = wBlinkOnTime;
g_stLedBlink[ucLedNum].wPeriod = wBlinkPeriod;ADP_SynLedBlink(ucLedNum);ulRet = CCU_OK;..;
default:50, "State led control type[%d] err", ucLedCtrl);ulRet = 167;..;}321;
36
UINT32 324;UINT8 ucVal = 0;UINT iCpldOffset = 0;UINT8 ucBitNum = 0;
/*此接口控制ID UART0-5灯*/if(ucLedNum <= LED_RUN){return 11;}
/*获取led编号对应的cpld寄存器地址及位号*/
GetLedCtrlBit(ucLedNum ,iCpldOffset, ucBitNum);switch(ucLedCtrl){
case LED_ON:ulRet = ADP_CPLD_Read(iCpldOffset, 1, &ucVal);
if(CCU_OK != ulRet){50, "ADP_CPLD_Read offset[0x%02X]", iCpldOffset);321;}

/*写0亮灯*/CLRBIT(ucVal, ucBitNum);ulRet = ADP_CPLD_Write(iCpldOffset, 1, &ucVal);break;
.. LED_OFF:
同上/*写1灭灯*/SETBIT(ucVal, ucBitNum);同上
.. LED_BLINK:
/*最小时间刻度为100ms*/wBlinkOnTime /= 100;wBlinkPeriod /= 100;
CHECK_LED_BLINK_PARA(); g_stLedBlink[ucLedNum].wOntime = wBlinkOnTime;
g_stLedBlink[ucLedNum].wPeriod = wBlinkPeriod;ulRet = CCU_OK;break;
default: 50, "State led control type[%d] err", ucLedCtrl);ulRet = 167;break;}321;
37
UINT32 324;if(ucLedCtrl >= LED_CTRL_TYPE_END){return 11;}
switch(ucLedNum){
case LED_ALARM: .. LED_RUN:ulRet = ADP_StateLed(ucLedNum, ucLedCtrl, wBlinkOnTime, wBlinkPeriod);
break;case LED_UART0: case ..1: case ..2: case ..3: case ..4:
case ..5: case LED_ID0: case ..1: case LED_CARD1: case ..2: case ..:
case ..:ulRet = ADP_CPLDLed(..);break;default: ulRet = 11;break;}321;
fsk_wyf 2011-09-13
  • 打赏
  • 举报
回复

32 return ulRet 321 g_lDriverSemId[DRIVER_SEM_AD0 + ucChn] 322 close(iADhandle) 323
ulRet = CCU_ERR 324
INT iMiliVolt = 0;..iADhandle ..;
.. iErrNo = AD_READ_TRYAGAIN; /*-11 返回值表示TRY AGAIN*/
UINT8 ucReadTime = 0;UINT32 324;CHECK
if(ucChn >= CCU_AD_CHN_NUM){50, "ADP_AD_Open chn num[%d] error", ucChn);return 167;}
if (CCU_OK != ADA_SmP(322, CCU_WAIT_FOREVER)){
/* 等待响应超时 */50, "ADP_AD_Read chn[%d] ADA_SmP timeout", ucChn);return CCU_ERR_MPI_SEM_TAKE_TIMEOUT;}
ulRet = ADP_AD_Open(ucChn, &iADhandle);if(CCU_OK != ulRet){50, "ADP_AD_Read ADP_AD_Open chn num[%d] error", ucChn);ADA_SmV(322);321;}
if(CCU_OK != ADP_AD_Config(iADhandle)){50, "ADP_AD_Read Config chn[%d] Error", ucChn);323;ADA_SmV(322);222;}

iErrNo = AD_READ_TRYAGAIN;
/* it is necessary to delay some time before read volt, after configuration */
/*-11 返回值表示TRY AGAIN*/
/*最多读5次*/
/*while((AD_READ_TRYAGAIN == iErrNo) && (ucReadTime < 5))*/
while((iErrNo < 0) && (ucReadTime < 5))
{ADA_Sleep(10);iErrNo = read(iADhandle, &iMiliVolt, 1);ucReadTime++;}
if(iErrNo < 0) {50, "Read ADC[%d], errno[%d]", ucChn, iErrNo);323;ADA_SmV(322);return 33;}
*piVal = iMiliVolt;/*DBG_DRVADP(LP_INFO, "Read ADC[%d]: %d", ucChn, iMiliVolt);*/323;ADA_SmV(322);221;
33 g_lDriverSemId[DRIVER_SEM_DS1820_0 + ucChn] 331 iTmp = (ucResult[0] * 10) >> 1 332
INT iTmp = 0;.. fp = ..;
UINT8 ucResult[2] = {0};// 从ds18b20读出的结果,result[0]存放低八位 CHAR acStrDir[32] = {'\0'};
if(ucChn >= CCU_DS1820_CHN_NUM){50, "DS1820 chn num cannot larger than %d", CCU_DS1820_CHN_NUM);167;}
CHECK;if (CCU_OK != ADA_SmP(331, CCU_WAIT_FOREVER))
{/* 等待响应超时 */50, "ADP_Read_DS1820 ADA_SmP timeout");return CCU_ERR_MPI_SEM_TAKE_TIMEOUT;}
43(acStrDir, sizeof(acStrDir), "/dev/ds1820-%d", ucChn);//fp = open(acStrDir, "r+"); fp = open(acStrDir, O_RDONLY);
if (fp < 0){50, "Open file[%s] fail", acStrDir);ADA_SmV(331);return 31;}
#if 0 /*启动转换*/41(ucResult, sizeof(char), 1, fp);usleep(1000);#endif
/*读取转换后的值 读2个字节*/
if(2 != read(fp, ucResult, 2)){close(fp);ADA_SmV(331);return 33;}
DBG_DRVADP(LP_INFO, "Read Temp:%d-%d", ucResult[1], ucResult[0]);
/*计算温度值*/
/*ucResult[1]为符号位 为0xff时为负 0 为正*/
if (ucResult[1] == 0xff){ucResult[0] = ~ucResult[0];ucResult[0] += 1;332;iTmp = -iTmp;}else{332;}*piVal = iTmp;
close(fp);DBG_DRVADP(LP_INFO, "Current Temperature:%d", iTmp);ADA_SmV(331);221;
chenzhuo 2011-09-13
  • 打赏
  • 举报
回复
[Quote=引用 39 楼 wanjianjun 的回复:]

引用 38 楼 chenzhuo 的回复:
呵呵,不能这么简单就实现吧。



请问楼主,费这么大劲自己实现一个心跳组件,你这个能有什么特别,与delphi自带的相比有什么不同之处吗?
[/Quote]

主要是WaitTimer比Timer更可靠,当到了规定的时间的时候,WaitTimer更有可能得到通知。

具体请参看 WINDOWS核心编程 9.4章节。
jingtuzhong 2011-09-13
  • 打赏
  • 举报
回复
谢谢楼主,分享
wanjianjun 2011-09-13
  • 打赏
  • 举报
回复
[Quote=引用 38 楼 chenzhuo 的回复:]
呵呵,不能这么简单就实现吧。
[/Quote]


请问楼主,费这么大劲自己实现一个心跳组件,你这个能有什么特别,与delphi自带的相比有什么不同之处吗?
chenzhuo 2011-09-13
  • 打赏
  • 举报
回复
呵呵,不能这么简单就实现吧。
lyhoo163 2011-09-11
  • 打赏
  • 举报
回复
支持。。
ccrun.com 2011-09-11
  • 打赏
  • 举报
回复
有点意思。
lyhoo163 2011-09-11
  • 打赏
  • 举报
回复
支持。。。
jingtuzhong 2011-09-11
  • 打赏
  • 举报
回复
xuexixue
chenzhuo 2011-09-11
  • 打赏
  • 举报
回复
按yushf的方法做了一修正版本,可以不用通过线程进入APC对列,
省去了管理线程资源和同步的问题。
RegisterWaitForSingleObject是一个不错的API。

再次感谢yushf和所有提意见的朋友。


unit WaitTimerU;

interface

uses
Classes, Windows, Consts, SysCall;

type
TWaitTimer = class(TComponent)
private
FWaitableTimer: THandle;
FWaitObject: THandle;
FInterval: Cardinal;
FOnTimer: TNotifyEvent;
FEnabled: Boolean;
procedure UpdateTimer;
procedure SetEnabled(Value: Boolean);
procedure SetInterval(Value: Cardinal);
procedure SetOnTimer(Value: TNotifyEvent);
protected
procedure Timer; dynamic;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Enabled: Boolean read FEnabled write SetEnabled default True;
property Interval: Cardinal read FInterval write SetInterval default 1000;
property OnTimer: TNotifyEvent read FOnTimer write SetOnTimer;
end;

function RegisterWaitForSingleObject(var phNewWaitObject: THandle; hObject: THandle;
Callback: Pointer; Context: Pointer; dwMilliseconds: DWORD; dwFlags: DWORD): BOOL; stdcall;
function UnregisterWait(WaitHandle: THandle): BOOL; stdcall;

implementation

function RegisterWaitForSingleObject; external kernel32;
function UnregisterWait; external kernel32;

procedure TimerAPCProc(lpParameter: Pointer; TimerOrWaitFired: BOOL); stdcall;
begin
TWaitTimer(lpParameter).Timer;
end;

{ TWaitTimer }

constructor TWaitTimer.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FEnabled := True;
FInterval := 1000;
FWaitableTimer := CreateWaitableTimer(nil, False, nil);
RegisterWaitForSingleObject(FWaitObject, FWaitableTimer, @TimerAPCProc, Self, INFINITE, 0);
end;

destructor TWaitTimer.Destroy;
begin
FEnabled := False;
UpdateTimer;
UnregisterWait(FWaitObject);
CloseHandle(FWaitableTimer);
inherited;
end;

procedure TWaitTimer.SetEnabled(Value: Boolean);
begin
if Value <> FEnabled then
begin
FEnabled := Value;
UpdateTimer;
end;
end;

procedure TWaitTimer.SetInterval(Value: Cardinal);
begin
if Value <> FInterval then
begin
FInterval := Value;
UpdateTimer;
end;
end;

procedure TWaitTimer.SetOnTimer(Value: TNotifyEvent);
begin
FOnTimer := Value;
UpdateTimer;
end;

procedure TWaitTimer.Timer;
begin
if Assigned(FOnTimer) then FOnTimer(Self);
end;

procedure TWaitTimer.UpdateTimer;
var
DueTime: Int64;
begin
CancelWaitableTimer(FWaitableTimer);
if (FInterval <> 0) and FEnabled and Assigned(FOnTimer) then
begin
DueTime := -Int64(Interval)*10000;
if not SetWaitableTimer(FWaitableTimer, DueTime, Interval, nil, nil , True) then
raise EOutOfResources.Create(SNoTimers);
end;
end;

end.

chenzhuo 2011-09-11
  • 打赏
  • 举报
回复
去掉多余的引用单元SysCall


unit WaitTimerU;

interface

uses
Classes, Windows, Consts;

type
TWaitTimer = class(TComponent)
private
FWaitableTimer: THandle;
FWaitObject: THandle;
FInterval: Cardinal;
FOnTimer: TNotifyEvent;
FEnabled: Boolean;
procedure UpdateTimer;
procedure SetEnabled(Value: Boolean);
procedure SetInterval(Value: Cardinal);
procedure SetOnTimer(Value: TNotifyEvent);
protected
procedure Timer; dynamic;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Enabled: Boolean read FEnabled write SetEnabled default True;
property Interval: Cardinal read FInterval write SetInterval default 1000;
property OnTimer: TNotifyEvent read FOnTimer write SetOnTimer;
end;

function RegisterWaitForSingleObject(var phNewWaitObject: THandle; hObject: THandle;
Callback: Pointer; Context: Pointer; dwMilliseconds: DWORD; dwFlags: DWORD): BOOL; stdcall;
function UnregisterWait(WaitHandle: THandle): BOOL; stdcall;

implementation

function RegisterWaitForSingleObject; external kernel32;
function UnregisterWait; external kernel32;

procedure TimerAPCProc(lpParameter: Pointer; TimerOrWaitFired: BOOL); stdcall;
begin
TWaitTimer(lpParameter).Timer;
end;

{ TWaitTimer }

constructor TWaitTimer.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FEnabled := True;
FInterval := 1000;
FWaitableTimer := CreateWaitableTimer(nil, False, nil);
RegisterWaitForSingleObject(FWaitObject, FWaitableTimer, @TimerAPCProc, Self, INFINITE, 0);
end;

destructor TWaitTimer.Destroy;
begin
FEnabled := False;
UpdateTimer;
UnregisterWait(FWaitObject);
CloseHandle(FWaitableTimer);
inherited;
end;

procedure TWaitTimer.SetEnabled(Value: Boolean);
begin
if Value <> FEnabled then
begin
FEnabled := Value;
UpdateTimer;
end;
end;

procedure TWaitTimer.SetInterval(Value: Cardinal);
begin
if Value <> FInterval then
begin
FInterval := Value;
UpdateTimer;
end;
end;

procedure TWaitTimer.SetOnTimer(Value: TNotifyEvent);
begin
FOnTimer := Value;
UpdateTimer;
end;

procedure TWaitTimer.Timer;
begin
if Assigned(FOnTimer) then FOnTimer(Self);
end;

procedure TWaitTimer.UpdateTimer;
var
DueTime: Int64;
begin
CancelWaitableTimer(FWaitableTimer);
if (FInterval <> 0) and FEnabled and Assigned(FOnTimer) then
begin
DueTime := -Int64(Interval)*10000;
if not SetWaitableTimer(FWaitableTimer, DueTime, Interval, nil, nil , True) then
raise EOutOfResources.Create(SNoTimers);
end;
end;

end.
chenzhuo 2011-09-06
  • 打赏
  • 举报
回复
刚测试了一下,确实可以,多谢yushf提供了一种简洁的解决方法。
chenzhuo 2011-09-06
  • 打赏
  • 举报
回复
谢谢分享
yushf 2011-09-06
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 chenzhuo 的回复:]

谢谢,能否告知RegisterWaitForSingleObject在那里定义吗?
[/Quote]
我都是从MSDN上查的,详细的你可以去那儿看。这有几个我常用的。

unit SysCall;
interface
uses
Windows;

const
// By default, the callback function is queued to a non-I/O worker thread.
WT_EXECUTEDEFAULT = $00000000;

// The callback function is invoked by the timer thread itself. This flag should be used only for short tasks or it could affect other timer operations.
// The callback function is queued as an APC. It should not perform alertable wait operations.
WT_EXECUTEINTIMERTHREAD = $00000020;

// The callback function is queued to an I/O worker thread. This flag should be used if the function should be executed in a thread that waits in an alertable state.
// The callback function is queued as an APC. Be sure to address reentrancy issues if the function performs an alertable wait operation.
WT_EXECUTEINIOTHREAD = $00000001;

// The callback function is queued to a thread that never terminates. It does not guarantee that the same thread is used each time. This flag should be used only for short tasks or it could affect other timer operations.
// Note that currently no worker thread is truly persistent, although no worker thread will terminate if there are any pending I/O requests.
WT_EXECUTEINPERSISTENTTHREAD = $00000080;

// The callback function can perform a long wait. This flag helps the system to decide if it should create a new thread.
WT_EXECUTELONGFUNCTION = $00000010;

// The timer will be set to the signaled state only once.
WT_EXECUTEONLYONCE = $00000008;

// Callback functions will use the current access token, whether it is a process or impersonation token. If this flag is not specified, callback functions execute only with the process token.
WT_TRANSFER_IMPERSONATION = $00000100;

type
TWaitOrTimerCallback = procedure(
lpParameter: pointer;
TimerOrWaitFired: BOOL
);stdcall;

function CreateTimerQueue: THandle;stdcall;
function DeleteTimerQueueEx(
TimerQueue: THandle;
CompletionEvent: THandle
): BOOL;stdcall;

function CreateTimerQueueTimer(
var phNewTimer: THandle;
TimerQueue: THandle;
Callback: pointer; // WAITORTIMERCALLBACK
Parameter: pointer;
DueTime: DWORD;
Period: DWORD;
Flags: ULONG
): BOOL;stdcall;
function DeleteTimerQueueTimer(
TimerQueue: THandle;
Timer: THandle;
CompletionEvent: THandle
): BOOL;stdcall;
function ChangeTimerQueueTimer(
TimerQueue: THandle;
Timer: THandle;
DueTime: ULONG;
Period: ULONG
): BOOL;stdcall;
function RegisterWaitForSingleObject(
var phNewWaitObject: THandle;
hObject: THandle;
Callback: pointer; // WAITORTIMERCALLBACK
Context: pointer;
dwMilliseconds: DWORD;
dwFlags: DWORD
): BOOL;stdcall;
function UnregisterWait(
WaitHandle: THandle
): BOOL;stdcall;
function UnregisterWaitEx(
WaitHandle: THandle;
CompletionEvent: THandle
): BOOL;stdcall;
function QueueUserWorkItem(
cbFunction: pointer; // LPTHREAD_START_ROUTINE
Context: pointer;
Flags: DWORD
): BOOL;stdcall;

function OpenThread(
dwDesiredAccess: DWORD;
bInheritHandle: BOOL;
dwThreadId: DWORD
): DWORD;stdcall;

// ATL functions
function AtlAxWinInit(): BOOL;stdcall;
function AtlAxAttachControl(
const pControl: IUnknown;
const hWnd: HWND;
out ppUnkContainer): HRESULT;cdecl;

implementation
const
atl = 'atl.dll';

function CreateTimerQueue;external kernel32;
function DeleteTimerQueueEx;external kernel32;
function CreateTimerQueueTimer;external kernel32;
function DeleteTimerQueueTimer;external kernel32;
function ChangeTimerQueueTimer;external kernel32;
function RegisterWaitForSingleObject;external kernel32;
function UnregisterWait;external kernel32;
function UnregisterWaitEx;external kernel32;
function QueueUserWorkItem;external kernel32;
function OpenThread;external kernel32;
// ATL functions
function AtlAxWinInit;external atl;
function AtlAxAttachControl;external atl;

end.

yushf 2011-09-05
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 chenzhuo 的回复:]

SetWaitableTimer(FWaitableTimer, DueTime, Interval, nil, 0, False);

之后没调用类似SleepEx 有Ex后缀的API函数能进入APC队列吗?

楼上的代码测试过吗?
[/Quote]

类似的代码我在项目中已使用。
不需要Timer的回调,所以不需要其进APC队列,现在是FhWaitObj进APC队列。
chenzhuo 2011-09-05
  • 打赏
  • 举报
回复
谢谢,能否告知RegisterWaitForSingleObject在那里定义吗?
加载更多回复(24)
1,01.zip
Dialogs in DLL
在DLL中实现对话框(5KB)
2,02.zip
Export dialogs in MFC Extension DLLs
在MFC扩充DLL中输出对话框(12KB)
3,03.zip
Remapping resource script ID's
重影象资源的标识符(4KB)
4,04.zip
Determine DLL version number
检测DLL的版本号(7KB)
5,05.zip
Getting the complete information about DLL/Exe module
得到DLL/EXE模块的编译信息(5KB)
6,06.zip
Using one extension DLL in another
在DLL中使用扩充的DLL(4KB)
7,07.zip
Handling VB strings (as part of an array of UDT)
VB的串句柄(5KB)
8,08.zip
Class for Dynamic DLL Loading
动态装入DLL的一个类(6KB)
9,pop3.zip
CPop3Connection - an MFC Class to encapsulate the POP3 protocol(20KB)
10,ipenum.zip
IPEnum - an MFC class and console app to allow IP address enumeration
(11KB)
11,smtp.zip
CSMTPConnection - an MFC Class to encapsulate the SMTP protocol(69KB)
12,ping.zip
CPing - an MFC class to encapsulate the PING protocol(13KB)
13,mailslot.zip
CServerMailslot & CClientMailslot - 2 MFC classes to support Win32 mailslots(29KB)
14,rasman.zip
A shareware application to monitor your Dial-Up Networking Connections.
(49KB)
15,rasmonitor.zip
The MFC class to monitor connections as used by RasMan.(17KB)
16,npipe.zip
A Freeware MFC class to encapsulate Named Pipes(24KB)
17,apipe.zip
A Freeware MFC class to encapsulate(8KB)
18,csntp.zip
A Freeware MFC class to encapsulate the SNTP protocol(18KB)
19,tracer.zip
an MFC class to encapsulate trace route functionality(13KB)
20,popwatch.zip
A freeware application to monitor your POP3 mailbox(72KB)
21,w3mfc.zip
A collection of freeware MFC classes to implement a Web Server(34KB)
22,mfccddb.zip
A freeware MFC class to support access to CDDB servers(39KB)
23,cmapi.zip
an MFC class to encapsulate sending mail using Simple MAPI(21KB)
24,finger.zip
An MFC class to encapsulate the "Finger" protocol(26KB)
25,eqd.zip
A Freeware MFC class to support retrieval of recent Earthquake data from the USGS(10KB)
26,httpdownloaddlg.zip
The class implements an MFC CDialog derived class which performs HTTP downloads similar to the Internet Explorer(43KB)
27,ccmc.zip
an MFC class to encapsulate sending mail using CMC(19KB)
28,ftptransferdlg.zip
CFTPTransferDlg provides an MFC dialog which performs FTP uploads and downloads similar to the Internet Explorer(43KB)
29,memmap.zip
A freeware MFC class to encapsulate Memory Mapped Files(18KB)
30,pstat.zip
A Freeware generalized framework for executing a lengthy operation in a thread. (20KB)
31,cfile64.zip
A freeware MFC class to encapsulate the Win32 64 bit file system API(16KB)
32,serv.zip
A class framework for developing NT services in MFC(53KB)
33,shelllink.zip
2 Freeware MFC classes to encapsulate shell shortcuts(12KB)
34,dyndata.zip
A collection of freeware MFC classes to encapsulate the Windows 95/98 performance counters.(10KB)
35,cpdh.zip
A collection of freeware MFC classes to encapsulate the NT Performance Counters.(25KB)
36,serialport.zip
A freeware MFC class for Win32 serial ports(19KB)
37,cpl_pp.zip
A freeware MFC class framework for developing Control Panel Applets(14KB)
38,parallelport.zip
An MFC class to control parallel ports on 95, 98, ME, NT and 2000(16KB)
39,versioninfo.zip
An MFC class to encapsulate the Windows Version API(14KB)
40,waitabletimer.zip
A freeware MFC class for Win32 waitable timers(13KB)
41,vfwwnd.zip
CAVICapWnd - AN MFC wrapper class for Video For WIndows(47KB)
42,fraction.zip
a double / fraction / string conversion class(5KB)
43,cmd5.zip
A C++ Message Digest 5 Class(13KB)
44,cryptit.zip
Keep sensitive data safe via encryption (130KB)
45,gener1.zip
Template functions for serializing arbitrary linked nodes.(25KB)
46,gener2.zip
Template functions for serializing arbitrary linked nodes. (3KB)
47,zip1.zip
The library to create, modify and extract zip archives(92KB)
48,zip2.zip
The library to create, modify and extract zip archives (31KB)
49,pointers.zip
A Beginner's Guide to Pointers
An article showing the use of pointers in C and C++ (4KB)
50,linkedlist_demo.zip
An article showing the basics of the linked list, and how the CList class operates (7KB)
51,ocarray_demo.zip
A simple derived template class that can boost the efficiency of your programs. (18KB)
52,clist_iter_src.zip
A simple iteration class for MFC's CList linked list (2KB)
53,dynopenhashtable_src.zip
Making assorted hash table of strings and/or other data types. (4KB)
54,extcol_demo.zip
Extended Collection classes to provide copy, compare and find operations with 2 dimensional arrays and maps (24KB)
55,extcol_src.zip
Extended Collection classes to provide copy, compare and find operations with 2 dimensional arrays and maps (11KB)
56,lookaside_src.zip
A simple way to keep items such as COM instances 'warm' and available for reuse (3KB)
57,isarray_src.zip
A simple templated array class. (2KB)
58,collectionnotes.zip
An article describing MFC Collection Classes (9KB)
59,qarray_demo.zip
A CArray derived class that provides quick and convenient sorting (13kb)
60,qarray_src.zip
A CArray derived class that provides quick and convenient sorting (2KB)
61,smartlist.zip
Wrapper classes for MFC list classes the extend their functionality (4KB)
62,ufstmaps.zip
A fully featured map class that uses balanced trees to store and retrieve data quickly by key (558KB)
63,qsort_demo.zip
An introduction to a useful function (15KB)
64,seexception_demo.zip
This article describes how to handle SE and C++ exception together(16KB)
65,seexception_src.zip
This article describes how to handle SE and C++ exception together(2KB)
66,circular_buffer_demo.zip
A circular, thread-safe read/write character buffer (12KB)
67,avltree_demo.zip
Describes an implementation of AVL Trees. (54KB)
68,metaclass_demo.zip
A class that can be modified at run-time (6KB)
69,metaclass_src.zip
A class that can be modified at run-time (4KB)
70,arrayex_src.zip
This article presents a callback based, QuickSort enabled CArray template class (2KB)
71,arrayex_demo.zip
This article presents a callback based, QuickSort enabled CArray template class (28KB)
72,chookwnd_src.zip
A freeware MFC class to support MFC subclassing (19KB)
73,cinifile_demo.zip
A class that makes it easy to implement an INI settings file in your applications(14KB)
74,cinifile_src.zip
A class that makes it easy to implement an INI settings file in your applications(4KB)
75,cint96_src.zip
A Freeware MFC class which provides 96 bit integers. (10KB)
76,csingleinst_src.zip
An MFC class to implement single instance apps. (9KB)
77,enitl.zip
A cross platform scripting engine for server applications providing HTML, XML, SGML or other text based formats (38KB)
78,floatutils_src.zip
A set of floating point utilities (3KB)
79,switch_languages.zip
Multilingual Application - Change Application Language(33KB)
80,duration_demo.zip
A simple class that provides high precision timing. (3KB)
81,duration_src.zip
A simple class that provides high precision timing. (1KB)
82,save_temp_var.zip
A safe, and convenient way to store variables temporarily (1KB)
83,tcxunitconverter_demo.zip
TCX Unit Conversion Library(18KB)
84,tcxunitconverter_src.zip
TCX Unit Conversion Library(7KB)
85,templates_demo.zip
Templates are a great way of reusing code, unfortunately MFC
makes it hard to write MFC friendly template classes... (124KB)
86,templates_src.zip
Templates are a great way of reusing code, unfortunately MFC
makes it hard to write MFC friendly template classes... (2KB)
87,functionparser.zip
A simple yet powerful function parser that parses and evaluates standard mathematical functions (82KB)
88,stlxmlparser.zip
This is a small non-validating XML parser based purely on STL (10KB)
89,xmimabparser_src.zip
A class to read and write non validated XML files (178KB)
90,rexsearch_src.zip
Compiles a regular expression into a fast automaton (11KB)
91,rexsearch_demo.zip
Compiles a regular expression into a fast automaton (50KB)
92,sascript.zip
A simple stack-based language that you can easily add to your projects (52KB)
93,strtok_src.zip
A customizable string tokenizer (23KB)
94,ismart_demo.zip
A template-based smart pointer implementation(19KB)
95,ismart_src.zip
A template-based smart pointer implementation(2KB)
96,smartptr.zip
A smart pointer wrapper class(4KB)
97,blockallocator.zip
A block allocator for use with STL containers that greatly improves speed in programs doing massive data insertions and extractions(6KB)
98,stltools.zip
Defines some TCHAR compatible STL elements and gives you an std::ostream to send output to the debugger windows. (4KB)
99,tokeniterator.zip
Token Iterator provides an easy to use, familiar, and customizable way in which to go through the tokens contained in a string (7KB)
100,stdsort.zip
An introduction to sorting using STL(4KB)
101,clniex_src.zip
Class CIniEx carries out extended set of ini-files functions in memory (106KB)
102,dtconverter.zip
A simple app that converts to and between time_t, DATE, and regular date string expressions(17KB)
103,dumphandle_demo.zip
A method of getting more details about application crashes.(24KB)
104,libdump.zip
A tool to display the contents of a library file (383KB)
105,vbactivexwithvc.zip
A simple way to call a VB ActiveX DLL from a VC/MFC Client(24KB)
106,staticlink.zip
VC++ Standard Edition only has support for dynamically linked exes. This article shows you how to by-pass this restriction.(14KB)
107,displayloadedmodules.zip
A Debugging Tool for Application using Multiple DLLs (246KB)
108,dynamicdiiloading_demo.zip
How to dynamically load a DLL (11KB)
109,hookimport_src.zip
A class to hook any imported function call made by your app.(7KB)
110,plug-in_demo.zip
Extending the functionality of your programs using explicit linking (60KB)
111,data_seg_share_demo.zip
Using #pragma statements to share variables in a DLL(37KB)
112,niftyloadlib_src.zip
The home of NiftyLoadLibrary - and some notes on rebasing dlls(3KB)
113,rcremap.zip
Remapping resource script ID's (21KB)
114,get_info.zip
Getting the complete information about DLL/Exe module (29KB)
115,vbstring.zip
Handling VB strings (as part of an array of UDT) (5KB)

828

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧