我在主程序中定义的过程和函数,在dll中怎么调用呢?送高分!!!! 在DLL中开辟一段内存,主程序运行后将你的DLL要调用的过程和函数地址保存到该内存中.然后DLL根据这些过程和函数地址进行调用. 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 delhpi 的 DLL机制不是很稳定,用内存管理的方法非常容易产生内存冲突,我不明白你为什么要在DLL 中调用主调程序的东西,,如果必要将被调用部分写成DLL, 同意skypeople说的。完全可以把两者都要调用的东西再做成一个DLL,这样原来的Main与DLL都可以调用了。 1、设置回调函数,函数指针作为参数(进程内);2、建立COM对象,添加EventSink处理(对于Delphi 5 创建派遣接口的回调事件将自动维护该方法)(推荐方法)。3、建立COM接口以及调用程序的回调接口(进程内/进程外均可,工作量大,但可全盘控制)。 我也想把调用部分写成dll的,但是这块部分用了动态加载控件,还用了hook,所以不方便写成dll,下面是主程序的原代码,我主要调用procedure info2ctrl 和沟子部分,怎样才能解决呢?我现在暂时给20分,有人解决 就会给高分的!!unit ufrmExecute;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, CommCtrl, StdCtrls, ShellApi, extctrls, ScktComp, zlclass, inifiles, ComCtrls, Grids, Math, Buttons;const WM_ItemInsert = WM_App + 1; //ListView中新增加item WM_ItemSetItem = WM_App + 2; //ListView中Item赋值 WM_ItemSetItemText = WM_App + 3; //ListView中Item赋值 WM_TEXTHOOK_EXCEPTION = WM_USER + $201;type TfrmExecute = class(TForm) tmConnect: TTimer; Label9: TLabel; sgrdXcuting: TStringGrid; Label2: TLabel; sgrdTask: TStringGrid; btnDelTask: TButton; aniDigital: TAnimate; btnStartUp: TButton; btnSetup: TButton; btnExit: TButton; btnStop: TButton; Bevel1: TBevel; lblCnn: TLabel; aniGlobal: TAnimate; lblTerminalID: TLabel; Bevel2: TBevel; lblRet: TLabel; lstRet: TListBox; lblGet: TLabel; lstGet: TListBox; lblFlex: TLabel; procedure btnExitClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure btnSetupClick(Sender: TObject); procedure btnStartUpClick(Sender: TObject); procedure CreateSocketConnection(); procedure ClientSocketConnect(Sender: TObject; Socket: TCustomWinSocket); procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket); procedure ClientSocketError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer); procedure btnLogKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure sgrdTaskDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); procedure FormClose(Sender: TObject; var Action: TCloseAction);// procedure btnLogClick(Sender: TObject); procedure btnDelTaskClick(Sender: TObject); procedure sgrdTaskSelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean); procedure FormDestroy(Sender: TObject); procedure tmConnectTimer(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure btnStopClick(Sender: TObject); procedure Info2Ctrlr(sCode, sAcctName, sStatus, sCnttCode, sNum, sPrice: string); //信息发送到控制端private nPriorTime: DWORD; //上一指令执行时的计数值 zlPrior: TZLRecord; //上一条执行的指令// procedure StopQuery; //收到停止查询指令后,从指令缓存表中将所有未执行的余额、余股查询指令删除 procedure UpdateConnectionIndicator(bConnected: boolean);public bProbeInstalled: Boolean; //TextOut 函数的钩子安装了与否 procedure BeginProbe(TargetHandle: THandle); //对目标窗口安装TextOut及ExtTextOut函数钩子 procedure EndProbe; //卸载TextOut及ExtTextOut函数钩子 ////以下是为获取ListView内容所用的各过程///////////////////////// remove function InstallListviewHook: boolean; //安装钩子,执行端启动时安装 function UninstallListviewHook: boolean; //卸载钩子,执行端关闭时卸载 procedure OnItemInsert(var Msg: TMessage); message WM_ItemInsert; procedure OnItemSetItem(var Msg: TMessage); message WM_ItemSetItem; procedure OnItemSetItemText(var Msg: TMessage); message WM_ItemSetItemText; procedure MsgExtTextout(var msg: TMessage); message WM_TEXTHOOK_EXCEPTION + 1; procedure MsgTextout(var msg: TMessage); message WM_TEXTHOOK_EXCEPTION + 2; procedure MsgCMPDC(var msg: TMessage); message WM_TEXTHOOK_EXCEPTION + 3; procedure ShowProberText(nCols: integer); procedure ShowReturnText(); procedure ShowFlexHandle(sFlexHandle: string);end; { 交易系统模块输出函数类型}type TIsStartUpSuccess = function(zl: TZLRecord): Boolean; stdcall; TCloseSystem = procedure; stdcall; TTradeBuyFunc = function(zl: TZLRecord): Boolean; stdcall; //买函数 TTradeSellFunc = function(zl: TZLRecord): Boolean; stdcall; //卖函数 TTradeChedanFunc = function(zl: TZLRecord): Boolean; stdcall; //撤单函数 TTradeQueryFundsFunc = function(zl: TZLRecord): Boolean; stdcall; //查询余额函数 TTradeQueryStockFunc = function(zl: TZLRecord): Boolean; stdcall; //查询余股函数 TTradeQueryOrderFunc = function(zl: TZLRecord): Boolean; stdcall; //成交查询函数//////定义当前交易系统类型记录////////////////////TCurrSys= record hCurr : THandle; SysName : string; IsStartUpSuccess : TIsStartUpSuccess; CloseSystem : TCloseSystem; TradeBuyFunc : TTradeBuyFunc; TradeSellFunc : TTradeSellFunc; TradeChedanFunc : TTradeChedanFunc; TradeQueryFundsFunc : TTradeQueryFundsFunc; TradeQueryStockFunc : TTradeQueryStockFunc; TradeQueryOrderFunc : TTradeQueryOrderFunc; end;var frmExecute: TfrmExecute; CurrSys: TCurrSys; sIPAddrCtrl : String;//控制端IP地址 g_sTrmnID : String;//本执行端序号{$IFDEF Debug} LogFile: TextFile;{$ENDIF}// g_sck: TClientSocket; ZLTable: TZLData; //指令缓存表 ZxTable: TPerformTable; //指令执行纪录表 WaitForCount: DWORD; //内部网络断开计时 MsgStruct: ^CWPSTRUCT; bCloseProgram: boolean; //是否关闭应用程序 bPriorZlSuccess: boolean; //上一条指令执行成功与否 sLVContent: array of array of string; //所取到的ListView的内容,每一行的内容为List中的一行值, //在取ListView内容之前,须将它清空 str: string; slTextOut, slXTextOut: TStringList; //TextOut、ExtTextOut函数钩子得到的字符串 function ListviewHookProc(iCode: Integer; WParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; far; //主程序用 /////////////////////////////////////////////////////////////////////////procedure CloseAll; //关闭所有系统procedure ParseCommand(sCommand: string); //分解命令字符串的各部分,并分析其有效性implementationuses SysSetup, GridClass, Dll16, unitGlobal, unitWinFunc;{$R *.DFM}//////////////////////////沟子过程开始//////////////////////////////////////procedure TfrmExecute.BeginProbe(TargetHandle: THandle); //对目标窗口安装TextOut及ExtTextOut函数钩子begin slXTextOut.Clear; slTextOut.Clear; if bProbeInstalled then EndProbe; SetDlgHandle16(Self.Handle); SetTargetHandle16(TargetHandle); if not bProbeInstalled then begin InstallProbe16; bProbeInstalled := True; end;end;procedure TfrmExecute.EndProbe; //卸载TextOut及ExtTextOut函数钩子begin if bProbeInstalled then UNInstallProbe16; bProbeInstalled := False;end;procedure TfrmExecute.MsgExtTextout(var msg: TMessage);begin if msg.WParam = 0 then Str := ''; if msg.LParam = 0 then slXTextOut.Add(str) else str := str + chr(Byte(msg.LParam));end;procedure TfrmExecute.MsgTextout(var msg: TMessage);begin if msg.WParam = 0 then Str := ''; if msg.LParam = 0 then slTextOut.Add(str) else str := str + chr(Byte(msg.LParam));end;function CMPDC(DC1, DC2: HWND): Boolean;var C1: HDC;begin C1 := WOWHandle32(DC1, 4); Result := WindowFromDC(C1) = DC2;end;procedure TfrmExecute.MsgCMPDC(var msg: TMessage);var a: Boolean;begin a := CMPDC(msg.wParam, msg.lParam); msg.Result := Integer(a);end;//安装钩子,执行端启动时安装////////////////////////////////////function TfrmExecute.InstallListviewHook: boolean;begin Result := False; if g_hHookProc <> 0 then Exit; //如果钩子已安装则退出 g_hHookProc := SetWindowsHookEx(WH_CALLWNDPROC, @ListviewHookProc, g_hinstApp, 0); //装钩子 Result := g_hHookProc <> 0; //返回钩子是否安装成功end;//卸载钩子,执行端关闭时卸载//////////////////////////function TfrmExecute.UninstallListviewHook: boolean;begin if g_hHookProc <> 0 then if UnhookWindowshookEx(g_hHookProc) then g_hHookProc := 0; //卸载钩子 Result := g_hHookProc = 0;end;////钩子处理过程/////////////////////function ListviewHookProc(iCode: Integer; WParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;var h: HWND;begin if iCode >= 0 then begin MsgStruct := pointer(lParam); h := Windows.FindWindow('TfrmExecute', '交易代理'); case MsgStruct^.message of LVM_INSERTITEM: begin //如果是ListView中增加一个Item,则 SendMessage(h, WM_ItemInsert, MsgStruct^.wParam, MsgStruct^.lParam); //发送WM_ItemInsert消息 end; LVM_SETITEM: begin //如果是给ListView中某一子Item赋值,则 SendMessage(h, WM_ItemSetItem, MsgStruct^.wParam, MsgStruct^.lParam); //发送WM_ItemSetItem消息 end; LVM_SETITEMTEXT: begin //如果是给ListView中某一子Item赋值,则 SendMessage(h, WM_ItemSetItemText, MsgStruct^.wParam, MsgStruct^.lParam); //发送WM_ItemSetItemText消息 end; end; end; Result := CallNextHookEx(g_hHookProc, iCode, wParam, lParam);end;///处理WM_ItemInsert消息//////////////////////////////procedure TfrmExecute.OnItemInsert(var Msg: TMessage);var meminfo: MEMORY_BASIC_INFORMATION; dwPro: DWORD; dwOldProtect, dwOldProtect2: DWord; aitem: LV_ITEM; aCount: Cardinal; tmpItemText: array[0..254] of Char; //临时保存ListView的item的值 hProc: THandle; //包含ListView的进程的句柄begin if g_hProcessId = 0 then exit; hProc := OpenProcess(PROCESS_ALL_ACCESS, true, g_hProcessId); //得到进程句柄,其中ProcessId在启动盛润或精信时赋值 Fillchar(memInfo, sizeof(MEMORY_BASIC_INFORMATION), $0); //置初值 dwPro := VirtualQueryEx(hProc, pointer(Msg.LParam), memInfo, sizeof(MEMORY_BASIC_INFORMATION)); if dwPro <> sizeof(MEMORY_BASIC_INFORMATION) then exit; if not VirtualProtectEx(hProc, pointer(Msg.LParam), sizeof(LV_ITEM), PAGE_EXECUTE_READ, @dwOldProtect) then exit; if not ReadProcessMemory(hProc, pointer(Msg.LParam), @aitem, sizeof(LV_ITEM), aCount) then exit; if not VirtualProtectEx(hProc, pointer(Msg.LParam), sizeof(LV_ITEM), dwOldProtect, @dwOldProtect2) then exit; dwPro := VirtualQueryEx(hProc, (aitem.pszText), memInfo, sizeof(MEMORY_BASIC_INFORMATION)); if dwPro <> sizeof(MEMORY_BASIC_INFORMATION) then exit; if not VirtualProtectEx(hProc, (aitem.pszText), 255, PAGE_EXECUTE_READ, @dwOldProtect) then exit; if not ReadProcessMemory(hProc, (aitem.pszText), @tmpItemText, 255, aCount) then exit; if Length(sLVContent) <= 0 then //如果接受数组长度小于等于0(表示要增加的是ListView中的第一个Item),则 SetLength(sLVContent, 1) //给接受数组设长度1 else if aitem.iItem > Length(sLVContent) - 1 then //如果要增加的Item的索引值大于接受数组的长度,则 SetLength(sLVContent, aitem.iItem + 1); //接受数组长度加1 SetLength(sLVContent[aitem.iItem], 1); sLVContent[aitem.iItem, 0] := tmpItemText; //将Item的文本值保存下来 VirtualProtectEx(hProc, (aitem.pszText), 255, dwOldProtect, @dwOldProtect2);end;///处理WM_ItemSetItem消息//////////////////////////////procedure TfrmExecute.OnItemSetItem(var Msg: TMessage);var meminfo: MEMORY_BASIC_INFORMATION; dwPro: DWORD; dwOldProtect, dwOldProtect2: DWord; aitem: LV_ITEM; tmp1, tmp2, tmp3: integer; aCount: Cardinal; tmpItemText: array[0..254] of Char; //临时保存ListView的item的值 hProc: THandle; //包含ListView的进程的句柄begin if g_hProcessId = 0 then exit; hProc := OpenProcess(PROCESS_ALL_ACCESS, true, g_hProcessId); //得到进程句柄,其中ProcessId在启动盛润或精信时赋值 Fillchar(memInfo, sizeof(MEMORY_BASIC_INFORMATION), $0); //置初值 dwPro := VirtualQueryEx(hProc, pointer(Msg.LParam), memInfo, sizeof(MEMORY_BASIC_INFORMATION)); if dwPro <> sizeof(MEMORY_BASIC_INFORMATION) then exit; if not VirtualProtectEx(hProc, pointer(Msg.LParam), sizeof(LV_ITEM), PAGE_EXECUTE_READ, @dwOldProtect) then exit; if not ReadProcessMemory(hProc, pointer(Msg.LParam), @aitem, sizeof(LV_ITEM), aCount) then exit; if not VirtualProtectEx(hProc, pointer(Msg.LParam), sizeof(LV_ITEM), dwOldProtect, @dwOldProtect2) then exit; dwPro := VirtualQueryEx(hProc, (aitem.pszText), memInfo, sizeof(MEMORY_BASIC_INFORMATION)); if dwPro <> sizeof(MEMORY_BASIC_INFORMATION) then exit; if not VirtualProtectEx(hProc, (aitem.pszText), 255, PAGE_EXECUTE_READ, @dwOldProtect) then exit; if not ReadProcessMemory(hProc, (aitem.pszText), @tmpItemText, 255, aCount) then exit; tmp1 := aitem.iSubItem; tmp2 := aitem.iItem; tmp3 := Length(sLVContent[tmp2]) - 1; if tmp1 > tmp3 then //如果要赋值的子项的索引值大于接受数组中第几行的长度,则 SetLength(sLVContent[tmp2], tmp1 + 1); //按受数组该行的长度加1 sLVContent[tmp2, tmp1] := tmpItemText; //保存该子项的文本值 VirtualProtectEx(hProc, (aitem.pszText), 255, dwOldProtect, @dwOldProtect2);end;///处理WM_ItemSetItemText消息//////////////////////////////procedure TfrmExecute.OnItemSetItemText(var Msg: TMessage);var meminfo: MEMORY_BASIC_INFORMATION; dwPro: DWORD; dwOldProtect, dwOldProtect2: DWord; aitem: LV_ITEM; ItemIndex: integer; tmp1, tmp2, tmp3: integer; aCount: Cardinal; tmpItemText: array[0..254] of Char; //临时保存ListView的item的值 hProc: THandle; //包含ListView的进程的句柄begin if g_hProcessId = 0 then exit; ItemIndex := Msg.WParam; hProc := OpenProcess(PROCESS_ALL_ACCESS, true, g_hProcessId); //得到进程句柄,其中ProcessId在启动盛润或精信时赋值 Fillchar(memInfo, sizeof(MEMORY_BASIC_INFORMATION), $0); //置初值 dwPro := VirtualQueryEx(hProc, pointer(Msg.LParam), memInfo, sizeof(MEMORY_BASIC_INFORMATION)); if dwPro <> sizeof(MEMORY_BASIC_INFORMATION) then exit; if not VirtualProtectEx(hProc, pointer(Msg.LParam), sizeof(LV_ITEM), PAGE_EXECUTE_READ, @dwOldProtect) then exit; if not ReadProcessMemory(hProc, pointer(Msg.LParam), @aitem, sizeof(LV_ITEM), aCount) then exit; if not VirtualProtectEx(hProc, pointer(Msg.LParam), sizeof(LV_ITEM), dwOldProtect, @dwOldProtect2) then exit; dwPro := VirtualQueryEx(hProc, (aitem.pszText), memInfo, sizeof(MEMORY_BASIC_INFORMATION)); if dwPro <> sizeof(MEMORY_BASIC_INFORMATION) then exit; if not VirtualProtectEx(hProc, (aitem.pszText), 255, PAGE_EXECUTE_READ, @dwOldProtect) then exit; if not ReadProcessMemory(hProc, (aitem.pszText), @tmpItemText, 255, aCount) then exit; tmp1 := aitem.iSubItem; tmp2 := ItemIndex; tmp3 := Length(sLVContent[tmp2]) - 1; if tmp1 > tmp3 then //如果要赋值的子项的索引值大于接受数组中第几行的长度,则 SetLength(sLVContent[tmp2], tmp1 + 1); //按受数组该行的长度加1 sLVContent[ItemIndex, tmp1] := tmpItemText; //保存该子项的文本值 VirtualProtectEx(hProc, (aitem.pszText), 255, dwOldProtect, @dwOldProtect2);end;///////////////////////////////////////沟子过程尾///////////////////////////////////返回控制端过程procedure TfrmExecute.Info2Ctrlr(sCode, sAcctName, sStatus, sCnttCode, sNum, sPrice: string);var s: string;begin s := g_sTrmnID + '@@' + sCode + '@@' + sAcctName + '@@' + sStatus + '@@' + sCnttCode + '@@' + sNum + '@@' + sPrice; if not (sAcctName = ' ') then g_slRet2Ctrl.Add(s); s := 'start' + s + 'end'; if Assigned(g_sck) and g_sck.Active then g_sck.Socket.SendText(s);end;procedure TfrmExecute.UpdateConnectionIndicator(bConnected: boolean);begin if bConnected then begin lblCnn.Caption := '已连通'; lblCnn.Color := clBlack; lblCnn.Font.Color := clRed; aniGlobal.Active := True; end else begin lblCnn.Caption := '未连通'; lblCnn.Font.Color := clBlue; lblCnn.Color := clRed; aniGlobal.Active := False; end;end;procedure TfrmExecute.ClientSocketError(Sender: TObject; Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);begin ErrorCode := 0;end;procedure TfrmExecute.CreateSocketConnection();begintry if Assigned(g_sck) and g_sck.Active then Exit; g_sck.Free; g_sck := nil; g_sck := TClientSocket.Create(Application); g_sck.Port := 23658; g_sck.OnConnect := ClientSocketConnect; g_sck.OnRead := ClientSocketRead; g_sck.OnError := ClientSocketError; g_sck.Address := sIPAddrCtrl; g_sck.Active := True;finallyend;end;procedure TfrmExecute.ClientSocketConnect(Sender: TObject; Socket: TCustomWinSocket);begin //如果内部网络断开,当Socket再次连上时,发送连通消息,以正确反映执行端的连接状态 Info2Ctrlr(_, _, 'report', _, _, _);end;procedure TfrmExecute.tmConnectTimer(Sender: TObject);begin if g_nNoAnswerCounter > 6 then begin CreateSocketConnection(); g_bNetConnected := False; end; UpdateConnectionIndicator(g_bNetConnected); Inc(g_nNoAnswerCounter);try Info2Ctrlr(_, _, 'connect', 'adsl', _, _);finallyend;end;procedure TfrmExecute.ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);var s: string; //控制端传来的操作命令字符串begin s := Socket.ReceiveText; //接收控制端传来的操作命令字符串 if s = 'answer' then begin //如果收到的是对询问的回应信息,则 g_nNoAnswerCounter := 0; g_bNetConnected := true; exit; //退出 end; if s = 'exit' then begin //如果收到的是'退出'指令,则 bCloseProgram := True; Application.Terminate; //终止执行端程序 exit; //退出 end; ParseCommand(s); //对指令串进行解析end;//分解命令字符串的各部分,并分析其有效性procedure ParseCommand(sCommand: string);const nNUM_DELI = 13 + 1; //命令字符串中'@@'的个数var i, nDeli, len, nCommand: Integer; StartPos, EndPos: Integer; sCmdArray: array of string; sCmd, sTmpCmd: string; sZLCode, sOpNumber, sSystemNo, sClientNo: string; tmpZhName: string; nLocDeli: array[1..nNUM_DELI] of Integer; zlRcvStatement: TZLRecord;begin sTmpCmd := Trim(sCommand); SetLength(sCmdArray, 0); while True do begin StartPos := Pos('start', sTmpCmd); if StartPos <= 0 then break; //对该指令串不作处理 EndPos := Pos('end', sTmpCmd); if EndPos <= 0 then break; //对该指令串不作处理 if EndPos <= StartPos then break; //对该指令串不作处理 SetLength(sCmdArray, Length(sCmdArray) + 1); sCmdArray[Length(sCmdArray) - 1] := Copy(sTmpCmd, StartPos + 5, EndPos - StartPos - 5); Delete(sTmpCmd, 1, EndPos + 2); end; for nCommand := 0 to Length(sCmdArray) - 1 do begin sCmd := sCmdArray[nCommand]; len := Length(sCmd); nDeli := 0; //取得命令字串中分隔符的位置及个数 i := 1; while i <= len do begin if (sCmd[i] = '@') and (sCmd[i + 1] = '@') then begin inc(nDeli); if nDeli <= nNUM_DELI then nLocDeli[nDeli] := i; inc(i); end; inc(i); end; if nDeli <> nNUM_DELI then begin //如果分隔符个数不等于指定数,则 frmExecute.Info2Ctrlr(sCmd, _, 'invalid', _, _, _); Continue; end; sZLCode := LowerCase(Trim(Copy(sCmd, 1, nLocDeli[1] - 1))); //从命令字串中截取指令编码部分 if sZLCode = '' then sZLCode := ' '; sSystemNo := LowerCase(Trim(Copy(sCmd, nLocDeli[2] + 2, nLocDeli[3] - nLocDeli[2] - 2))); //从命令字串中截取系统编号部分 sClientNo := Trim(Copy(sCmd, nLocDeli[5] + 2, nLocDeli[6] - nLocDeli[5] - 2)); tmpZhName := Trim(Copy(sCmd, nLocDeli[12] + 2, nLocDeli[13] - nLocDeli[12] - 2)); //取得帐户名 if (sSystemNo <> 'jingxin') and (sSystemNo <> 'guotong') and (sSystemNo <> 'julin') and (sSystemNo <> 'pa18') and (sSystemNo <> 'minfa') and (sSystemNo <> 'gtja') and (sSystemNo <> 'feihu') and (sSystemNo <> 'tqzq') and (sSystemNo <> 'haitong') and (sSystemNo <> 'guangfa') and (sSystemNo <> 'guoxin') and (sSystemNo <> 'feihu') then begin //qj 待定 //如果命令字串中要求的交易系统软件终端未安装则 frmExecute.Info2Ctrlr(sZLCode, tmpZhName, 'invalid', _, _, _); Continue; end; sOpNumber := LowerCase(Trim(Copy(sCmd, nLocDeli[7] + 2, nLocDeli[8] - nLocDeli[7] - 2))); //从命令字串中截取操作编号部分 //对命令字串中的操作编码分析,判断是否为已定义的操作编码之一 if (sOpNumber <> 'buy') and (sOpNumber <> 'sell') and (sOpNumber <> 'chedan') and (sOpNumber <> 'yecx') and (sOpNumber <> 'ygcx') and (sOpNumber <> 'cjcx') then begin //如果不是已定义的操作编码则退出 frmExecute.Info2Ctrlr(sZLCode, tmpZhName, 'invalid', _, _, _); Continue; end; frmExecute.Info2Ctrlr(sZLCode, tmpZhName, 'valid', _, _, _); //向控制端发送合法信息 //指令串合法,将各部分分解出来,赋予指令纪录,并写入指令缓存表 with zlRcvStatement do begin StrPCopy(ZLCode, sZLCode); try Priority := strtoint(Trim(Copy(sCmd, nLocDeli[1] + 2, nLocDeli[2] - nLocDeli[1] - 2))); except Priority := 3; //默认3 end; StrPCopy(SystemNo, sSystemNo); StrPCopy(YuanJianNo, Trim(Copy(sCmd, nLocDeli[3] + 2, nLocDeli[4] - nLocDeli[3] - 2))); StrPCopy(YuanJianPassword, Trim(Copy(sCmd, nLocDeli[4] + 2, nLocDeli[5] - nLocDeli[4] - 2))); StrPCopy(GuDongCode, sClientNo); ///////////盛润金地营业部的深市股东代码长度为10位,需要在传过来的股东代码前加'02'///////////////////// if (StockJobber = '国泰金地') and (Length(StrPas(GuDongCode)) = 8) then StrPCopy(GuDongCode, '02' + StrPas(GuDongCode)); StrPCopy(GuDongPassword, Trim(Copy(sCmd, nLocDeli[6] + 2, nLocDeli[7] - nLocDeli[6] - 2))); StrPCopy(CaoZuoNo, sOpNumber); StrPCopy(StockCode, Trim(Copy(sCmd, nLocDeli[8] + 2, nLocDeli[9] - nLocDeli[8] - 2))); StrPCopy(StockCount, Trim(Copy(sCmd, nLocDeli[9] + 2, nLocDeli[10] - nLocDeli[9] - 2))); StrPCopy(StockPrice, Trim(Copy(sCmd, nLocDeli[10] + 2, nLocDeli[11] - nLocDeli[10] - 2))); StrPCopy(StockJobber, Trim(Copy(sCmd, nLocDeli[11] + 2, nLocDeli[12] - nLocDeli[11] - 2))); StrPCopy(AccountName, tmpZhName); ////////////////////////////////////////////////////////////////////////////////////////////////////// PerformTime := Time + StrToInt(Trim(Copy(sCmd, nLocDeli[13] + 2, nLocDeli[14] - nLocDeli[13] - 2))) / (24 * 60 * 60); StrPCopy(StockKind, Trim(Copy(sCmd, nLocDeli[14] + 2, Length(sCmd) - nLocDeli[13] - 1))); end; ZLTable.AppendNewRecord(zlRcvStatement); //写入指令缓存表 with frmExecute.sgrdTask, zlRcvStatement do begin if Cells[5, 1] <> '' then RowCount := RowCount + 1; Cells[0, RowCount - 1] := StrPas(ZLCode); Cells[1, RowCount - 1] := inttostr(Priority); Cells[2, RowCount - 1] := StrPas(SystemNo); Cells[3, RowCount - 1] := StrPas(AccountName); Cells[4, RowCount - 1] := StrPas(GuDongCode); Cells[5, RowCount - 1] := StrPas(CaoZuoNo); Cells[6, RowCount - 1] := StrPas(StockCode); Cells[7, RowCount - 1] := StrPas(StockCount); Cells[8, RowCount - 1] := StrPas(StockPrice); Cells[9, RowCount - 1] := StrPas(StockJobber); Cells[10, RowCount - 1] := TimeToStr(Time); end; end;end;//在创建窗体的时候,初始化系统参数//////////////////////////////////////procedure TfrmExecute.FormCreate(Sender: TObject);var GridTable: TGridClass; SetupIni: TIniFile; GridSetup: ReturnRecord; i: integer; FilePath: string; zlRcv: TZLRecord;begin btnStop.Enabled := False; btnStartUp.Enabled := True; btnExit.Enabled := True; btnSetup.Enabled := True; g_bNetConnected := false; lblFlex.Caption := ''; frmExecute.Caption := '交易代理';{$IFDEF Debug} AssignFile(LogFile, 'Debug.log');{$ENDIF} SetupIni := TIniFile.Create(ExtractFilePath(Application.ExeName) + '\' + 'syssetup.ini');// ShenYunAppname := SetupIni.ReadString('AppPath', 'ShenYunAppname', '');// JingXinAppname := SetupIni.ReadString('AppPath', 'JingXinAppname', ''); // Feihu :=SetupIni.ReadString('AppPath' , 'Feihu' ,''); //qj //GuoTong := SetupIni.ReadString('AppPath', 'GuoTong', ''); // JuLin := SetupIni.ReadString('AppPath', 'JuLin', ''); // MinFa := SetupIni.ReadString('AppPath', 'MinFa', '');// PingAnAppname := SetupIni.ReadString('AppPath', 'PingAnAppname', '');// GuangFaAppname := SetupIni.ReadString('AppPath', 'GuangFaAppname', ''); // sGFa := SetupIni.ReadString('AppPath', 'GFa', ''); // sHait := SetupIni.ReadString('AppPath', 'Hait', ''); // guoxin := SetupIni.ReadString('AppPath', 'guoxin', ''); // sPA18 := SetupIni.ReadString('AppPath', 'PA18', ''); // sTequzq := SetupIni.ReadString('AppPath', 'Tequzq', ''); sIPAddrCtrl := SetupIni.ReadString('WinSocket', 'IPAddrCtrl', '127.0.0.1'); g_sTrmnID := SetupIni.ReadString('WinSocket', 'TrmnID', '1'); //如未设置,则默认为第一执行端 SetupIni.Free; lblTerminalID.Caption := g_sTrmnID; //变量赋初始值 bCloseProgram := False; g_hProcessId := 0; //SetLength(sLVContent, 0); //对保存接收指令和已执行完指令的StringGrid初始化 GridTable := TGridClass.Create(ExtractFilePath(Application.ExeName) + '\' + 'GridSetup.dat'); GridTable.ReadColWidth(0, GridSetup); if GridSetup.ColsRead > 0 then with sgrdTask do begin for i := 0 to Min(GridSetup.ColsRead, ColCount) - 1 do ColWidths[i] := GridSetup.ColsWidth[i]; end; GridTable.ReadColWidth(1, GridSetup); GridTable.ReadColWidth(2, GridSetup); if GridSetup.ColsRead > 0 then with sgrdXcuting do begin for i := 0 to Min(GridSetup.ColsRead, ColCount) - 1 do ColWidths[i] := GridSetup.ColsWidth[i]; end; GridTable.ReadColWidth(3, GridSetup); GridTable.Free; with sgrdTask do begin Cells[0, 0] := '指令编码'; Cells[1, 0] := '优先权'; Cells[2, 0] := '系统编号'; Cells[3, 0] := '帐户名称'; Cells[4, 0] := '股东代码'; Cells[5, 0] := '操作类型'; Cells[6, 0] := '股票代码'; Cells[7, 0] := '委托股数'; Cells[8, 0] := '委托价格'; Cells[9, 0] := '证券公司'; Cells[10, 0] := '到达时间'; end; with sgrdXcuting do begin Cells[0, 0] := '指令编码'; Cells[1, 0] := '优先权'; Cells[2, 0] := '系统编号'; Cells[3, 0] := '帐户名称'; Cells[4, 0] := '股东代码'; Cells[5, 0] := '操作类型'; Cells[6, 0] := '股票代码'; Cells[7, 0] := '委托股数'; Cells[8, 0] := '委托价格'; Cells[9, 0] := '证券公司'; end;// DisplayZxRecord;//显示指令执行纪录 nPriorTime := 0; ZLTable := TZLData.Create(ExtractFilePath(Application.ExeName), 'ZLTable.dat'); //初始化指令缓存表类 ZxTable := TPerformTable.Create(ExtractFilePath(Application.ExeName), 'ZXTable.dat'); //初始化指令执行纪录表 //将指令表中现有纪录显示出来 with ZLTable, sgrdTask do begin for i := 0 to RecordCount - 1 do begin GetOneRecord(i, zlRcv); if Cells[5, 1] <> '' then RowCount := RowCount + 1; Cells[0, RowCount - 1] := StrPas(zlRcv.ZLCode); Cells[1, RowCount - 1] := inttostr(zlRcv.Priority); Cells[2, RowCount - 1] := StrPas(zlRcv.SystemNo); Cells[3, RowCount - 1] := StrPas(zlRcv.AccountName); Cells[4, RowCount - 1] := StrPas(zlRcv.GuDongCode); Cells[5, RowCount - 1] := StrPas(zlRcv.CaoZuoNo); Cells[6, RowCount - 1] := StrPas(zlRcv.StockCode); Cells[7, RowCount - 1] := StrPas(zlRcv.StockCount); Cells[8, RowCount - 1] := StrPas(zlRcv.StockPrice); Cells[9, RowCount - 1] := StrPas(zlRcv.StockJobber); Cells[10, RowCount - 1] := ''; end; if RecordCount > 0 then btnDelTask.Enabled := True; end;// g_RetMsg := TReturnMsg.Create(ExtractFilePath(Application.ExeName), 'ReturnMsg.dat'); //初始化指令缓存表类 //三个Animate载入文件 FilePath := ExtractFilePath(Application.ExeName); aniDigital.FileName := FilePath + '\' + 'Count24.avi'; aniGlobal.FileName := FilePath + '\' + 'globe.avi'; LoadDll16; bProbeInstalled := False; slTextOut := TStringList.Create; slXTextOut := TStringList.Create;end;procedure TfrmExecute.btnStartUpClick(Sender: TObject);var zl: TZLRecord; //将要执行的指令 i, nSec, nOpCode: integer; rec: TPerformRecord;begin lstRet.Clear; lstGet.Clear; lblFlex.Caption := ''; tmConnect.Enabled := True; btnSetup.Enabled := false; btnStartUp.Enabled := False; btnStartUp.default := False; btnStop.Enabled := True; btnStop.default := True; g_bNetConnected := true; g_bButtonPushed := True; CreateSocketConnection(); bCloseProgram := False; while not bCloseProgram do begin UpdateConnectionIndicator(g_bNetConnected); if g_bCurrTaskDeleted then begin with sgrdTask do begin for i := 2 to RowCount - 1 do Rows[i - 1] := Rows[i]; if RowCount > 2 then RowCount := RowCount - 1 else Rows[1].Clear; end; end; Application.HandleMessage; if nPriorTime > 0 then begin nSec := Ceil((GetTickCount - nPriorTime) / 1000); //得到上一指令执行的秒数 nOpCode := 0; if (zlPrior.CaoZuoNo = 'buy') then nOpCode := 1 else if (zlPrior.CaoZuoNo = 'sell') then nOpCode := 2 else if (zlPrior.CaoZuoNo = 'chedan') then nOpCode := 3 else if (zlPrior.CaoZuoNo = 'cjcx') then nOpCode := 4 else if (zlPrior.CaoZuoNo = 'yecx') then nOpCode := 5 else if (zlPrior.CaoZuoNo = 'ygcx') then nOpCode := 6; if nOpCode > 0 then begin g_slRet2Ctrl.Clear; ShowReturnText(); rec.Date := Date; rec.SystemNo := zlPrior.SystemNo; rec.CaoZuoCode := nOpCode; rec.CaoZuoName := sOPR_NAME[nOpCode]; rec.SuccessFail := bPriorZlSuccess; rec.HaoShi := nSec; ZxTable.AppendRecord(rec); ZxTable.Post; end; end; if ZLTable.RecordCount > 0 then begin ZLTable.GetFirstTask(zl); //得到优先权最高的那条指令 g_bCurrTaskDeleted := false; end; if (ZLTable.RecordCount <= 0) or (zl.PerformTime > Time) then begin //如果指令缓存表为空,则不作处理,开始下一次循环 with sgrdXcuting do begin //如果显示正在执行的指令的网格不为空,则清空 if Cells[5, 1] <> '' then for i := 0 to ColCount - 1 do Cells[i, 1] := ''; end; if aniDigital.Active then aniDigital.Active := False; //停止转动显示牌 zlPrior.CaoZuoNo := ''; nPriorTime := 0; Continue; end; Application.HandleMessage; with sgrdXcuting do begin Cells[0, 1] := StrPas(zl.ZLCode); Cells[1, 1] := inttostr(zl.Priority); Cells[2, 1] := StrPas(zl.SystemNo); Cells[3, 1] := StrPas(zl.AccountName); Cells[4, 1] := StrPas(zl.GuDongCode); Cells[5, 1] := StrPas(zl.CaoZuoNo); Cells[6, 1] := StrPas(zl.StockCode); Cells[7, 1] := StrPas(zl.StockCount); Cells[8, 1] := StrPas(zl.StockPrice); Cells[9, 1] := StrPas(zl.StockJobber); end; nPriorTime := GetTickCount; bPriorZlSuccess := False; if not aniDigital.Active then aniDigital.Active := True; zlPrior := zl; /////////////调用Dll/////////////// { Load the DLL and get all the procedure addresses. } if CurrSys.SysName <>zl.SystemNo then begin if Assigned(CurrSys.CloseSystem) then CurrSys.CloseSystem; FreeLibrary (CurrSys.hCurr); CurrSys.SysName:=zl.SystemNo ; CurrSys.hCurr := LoadLibrary(PChar('C:\DLLS\'+CurrSys.SysName+'.'+'dll')); CurrSys.IsStartUpSuccess:=(GetProcAddress(CurrSys.hCurr,'IsStartUpSuccess')); CurrSys.TradeBuyFunc:= (GetProcAddress(CurrSys.hCurr, 'TradeBuyFunc')); CurrSys.TradeSellFunc:=(GetProcAddress(CurrSys.hCurr, 'TradeSellFunc')); CurrSys.TradeChedanFunc:=(GetProcAddress(CurrSys.hCurr, 'TradeChedanFunc')); CurrSys.TradeQueryStockFunc:=(GetProcAddress(CurrSys.hCurr, 'TradeQueryStockFunc')); CurrSys.TradeQueryFundsFunc:=(GetProcAddress(CurrSys.hCurr, Pointer(3))); CurrSys.TradeQueryOrderFunc:=(GetProcAddress(CurrSys.hCurr, 'TradeQueryOrderFunc')); end; CurrSys.IsStartUpSuccess(zl) ; if zl.CaoZuoNo ='buy' then begin if zl.SystemNo =CurrSys.SysName then CurrSys.TradeBuyFunc(zl); end else if zl.CaoZuoNO='sell' then begin if zl.SystemNo =CurrSys.SysName then CurrSys.TradeSellFunc(zl); end else if zl.CaoZuoNo='chedan' then begin if zl.SystemNo =CurrSys.SysName then CurrSys.TradeChedanFunc(zl); end else if zl.CaoZuoNo='yecx' then begin if zl.SystemNo =CurrSys.SysName then CurrSys.TradeQueryFundsFunc(zl); end else if zl.CaoZuoNo='ygcx' then begin if zl.SystemNo =CurrSys.SysName then CurrSys.TradeQueryStockFunc(zl); end else if zl.CaoZuoNo='cjcx' then begin if zl.SystemNo =CurrSys.SysName then CurrSys.TradeQueryOrderFunc(zl); end; end; /////////////////////////////////////////////////////////////////////// { if (zl.CaoZuoNo = 'buy') then begin if zl.SystemNo = 'HEXIN_FEIHU.DLL' then hexinFeihu.TradeBuyFunc(zl); end else if zl.CaoZuoNo = 'sell' then begin if zl.SystemNo ='HEXIN_FEIHU.DLL' then hexinFeihu.TradeSellFunc(zl); end else if zl.CaoZuoNo = 'chedan' then begin if zl.SystemNo = 'HEXIN_FEIHU.DLL' then hexinFeihu.TradeChedanFunc(zl); end else if zl.CaoZuoNo = 'yecx' then begin if zl.SystemNo = 'HEXIN_FEIHU.DLL' then hexinFeihu.TradeQueryFundsFunc(zl); end else if zl.CaoZuoNo = 'ygcx' then begin if zl.SystemNo = 'HEXIN_FEIHU.DLL' then hexinFeihu.TradeQueryStockFunc(zl); end else if zl.CaoZuoNo = 'cjcx' then begin if zl.SystemNo = 'HEXIN_FEIHU.DLL' then hexinFeihu.TradeQueryOrderFunc(zl); end else if not g_bCurrTaskDeleted then g_bCurrTaskDeleted := ZLTable.DelFirstTask; frmExecute.ShowReturnText(); end; }end;/////////调用系统设置界面////////////////////////////procedure TfrmExecute.btnSetupClick(Sender: TObject);begin frmSysSetup := TfrmSysSetup.Create(Application); frmSysSetup.ShowModal; frmSysSetup.Free;end;procedure TfrmExecute.btnLogKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);begin if Key = vk_F1 then Application.HelpContext(2);end;procedure TfrmExecute.sgrdTaskDrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState);var tmpLeft, tmpTop: integer; tmpWidth: integer; TextToOut: string;begin with Sender as TStringGrid do begin if gdFixed in State then Canvas.Brush.Color := clBtnFace //设固定行底色 else if (Sender = sgrdTask) and (ARow = Row) and (btnDelTask.Enabled) then Canvas.Brush.Color := clAqua else Canvas.Brush.Color := Color; Canvas.FillRect(Rect); Canvas.Font := Font; if ARow > 0 then Canvas.Font.Name := 'MS Sans Serif'; TextToOut := Cells[ACol, ARow]; tmpWidth := Canvas.TextWidth(TextToOut); while tmpWidth > (Rect.Right - Rect.Left) do begin Delete(TextToOut, Length(TextToOut) - 1, 2); tmpWidth := Canvas.TextWidth(TextToOut); end; tmpLeft := (((Rect.Right - Rect.Left) - tmpWidth) div 2) + Rect.Left; tmpTop := (((Rect.Bottom - Rect.Top) - Canvas.TextHeight(Cells[ACol, ARow])) div 2) + Rect.Top; Canvas.TextOut(tmpLeft, tmpTop, TextToOut); end;end;procedure TfrmExecute.FormClose(Sender: TObject; var Action: TCloseAction);var GridTable: TGridClass; WidthToSave: array[0..128] of Word; i: integer;begin bCloseProgram := True; tmConnect.Enabled := False; GridTable := TGridClass.Create(ExtractFilePath(Application.ExeName) + '\' + 'GridSetup.dat'); with sgrdTask do begin for i := 0 to ColCount - 1 do WidthToSave[i] := ColWidths[i]; GridTable.SaveColWidth(0, WidthToSave, ColCount); end; with sgrdXcuting do begin for i := 0 to ColCount - 1 do WidthToSave[i] := ColWidths[i]; GridTable.SaveColWidth(2, WidthToSave, ColCount); end; GridTable.Free; // if g_bHookInstalled then g_bHookInstalled := not UninstallListviewHook; //卸载钩子end;{procedure TfrmExecute.btnLogClick(Sender: TObject);begin frmZxRecordEdit := TfrmZxRecordEdit.Create(Application); frmZxRecordEdit.ShowModal; frmZxRecordEdit.Free;end;}procedure TfrmExecute.btnDelTaskClick(Sender: TObject);var i: integer;begin ZLTable.DeleteOneRecord(sgrdTask.Row - 1); with sgrdTask do begin for i := 2 to RowCount - 1 do Rows[i - 1] := Rows[i]; if RowCount > 2 then RowCount := RowCount - 1 else Rows[1].Clear; end; if sgrdTask.Cells[5, 1] = '' then begin btnDelTask.Enabled := False; sgrdTask.Repaint; end;end;procedure TfrmExecute.sgrdTaskSelectCell(Sender: TObject; ACol, ARow: Integer; var CanSelect: Boolean);var co: Integer;begin with TStringGrid(Sender) do for co := 0 to ColCount - 1 do begin Cells[co, Row] := Cells[co, Row]; Cells[co, ARow] := Cells[co, ARow]; end;end;procedure TfrmExecute.FormDestroy(Sender: TObject);begin if Assigned(ZxTable) then ZxTable.Free; if Assigned(ZlTable) then ZLTable.Free;end;procedure TfrmExecute.btnExitClick(Sender: TObject);begin Close; Application.Terminate;end;procedure TfrmExecute.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);begin if Key = VK_escape then Close;end;procedure TfrmExecute.btnStopClick(Sender: TObject);begin Info2Ctrlr(_, _, 'disconnect', _, _, _); g_bButtonPushed := False; g_bNetConnected := false; tmConnect.Enabled := False; bCloseProgram := True; btnSetup.Enabled := True; btnStartUp.Enabled := True; btnStartUp.Default := True; btnStop.Enabled := False; btnStop.Default := False; aniDigital.Active := False; //停止转动显示牌 aniGlobal.Active := False; // if g_bHookInstalled then g_bHookInstalled := not UninstallListviewHook; //卸载钩子 if sgrdTask.Cells[5, 1] <> '' then btnDelTask.Enabled := True; UpdateConnectionIndicator(g_bNetConnected); if not Assigned(g_sck) then Exit; g_sck.Free; g_sck := nil;end;procedure TfrmExecute.ShowReturnText();var i: Integer;begin for i := 0 to g_slRet2Ctrl.Count - 1 do lstRet.Items.Add(g_slRet2Ctrl.Strings[i]);end;procedure TfrmExecute.ShowProberText(nCols: integer);var i, j, nRows: Integer; s: string;begin lstGet.Clear; nRows := g_slProberGet.Count div nCols; for i := 0 to nRows - 1 do begin s := ''; for j := 0 to nCols - 2 do begin s := s + g_slProberGet.Strings[i * ncols + j] + ' '; end; lstGet.Items.Add(s); end;end;procedure TfrmExecute.ShowFlexHandle(sFlexHandle: string);begin lblFlex.Caption := 'FlexGrid句柄:' + sFlexHandle;end;end. 我有一个dLL和EXE相互调用(EXE调用DLL的procedure时被调用的DLL的procedure调用EXE的procedure)的源代码,要的话可以发邮件到[email protected] 給我也發一分: [email protected]在此先谢谢 了! 用interface,做回调参考COM 请教DBGridEh新增或删除一行数据前如何加入判断条件 编译好的delphi程序,需要安装什么软件可以使其支持数据库 各位高手大哥大姐,问一个很简单的问题 listview和treeview问题,在线等 (50分) IdHTTP下载过程中程序为什么停止响应? 关于线程,高手帮忙,我把代码贴出来了!! 怎样可以获得Delphi里面的一些源码??100分 一个怪问题,为什么现在我的quickrep控件都没法放到窗体里,老是报错。请进来看看。 这样的ado怎么能用? delphi控件与sql server 不匹配问题: strpas是什么函数呀 如何才能与ADO组件连上来显示数据?
1、设置回调函数,函数指针作为参数(进程内);2、建立COM对象,添加EventSink处理(对于Delphi 5 创建派遣接口的回调事件将自动维护该方法)(推荐方法)。3、建立COM接口以及调用程序的回调接口(进程内/进程外均可,工作量大,但可全盘控制)。
unit ufrmExecute;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, CommCtrl,
StdCtrls, ShellApi, extctrls, ScktComp, zlclass, inifiles, ComCtrls, Grids, Math, Buttons;const
WM_ItemInsert = WM_App + 1; //ListView中新增加item
WM_ItemSetItem = WM_App + 2; //ListView中Item赋值
WM_ItemSetItemText = WM_App + 3; //ListView中Item赋值
WM_TEXTHOOK_EXCEPTION = WM_USER + $201;
type
TfrmExecute = class(TForm)
tmConnect: TTimer;
Label9: TLabel;
sgrdXcuting: TStringGrid;
Label2: TLabel;
sgrdTask: TStringGrid;
btnDelTask: TButton;
aniDigital: TAnimate;
btnStartUp: TButton;
btnSetup: TButton;
btnExit: TButton;
btnStop: TButton;
Bevel1: TBevel;
lblCnn: TLabel;
aniGlobal: TAnimate;
lblTerminalID: TLabel;
Bevel2: TBevel;
lblRet: TLabel;
lstRet: TListBox;
lblGet: TLabel;
lstGet: TListBox;
lblFlex: TLabel;
procedure btnExitClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btnSetupClick(Sender: TObject);
procedure btnStartUpClick(Sender: TObject);
procedure CreateSocketConnection();
procedure ClientSocketConnect(Sender: TObject; Socket: TCustomWinSocket);
procedure ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
procedure ClientSocketError(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
procedure btnLogKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure sgrdTaskDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
// procedure btnLogClick(Sender: TObject);
procedure btnDelTaskClick(Sender: TObject);
procedure sgrdTaskSelectCell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);
procedure FormDestroy(Sender: TObject);
procedure tmConnectTimer(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure btnStopClick(Sender: TObject);
procedure Info2Ctrlr(sCode, sAcctName, sStatus, sCnttCode, sNum, sPrice: string); //信息发送到控制端
private
nPriorTime: DWORD; //上一指令执行时的计数值
zlPrior: TZLRecord; //上一条执行的指令
// procedure StopQuery; //收到停止查询指令后,从指令缓存表中将所有未执行的余额、余股查询指令删除
procedure UpdateConnectionIndicator(bConnected: boolean);
public
bProbeInstalled: Boolean; //TextOut 函数的钩子安装了与否
procedure BeginProbe(TargetHandle: THandle); //对目标窗口安装TextOut及ExtTextOut函数钩子
procedure EndProbe; //卸载TextOut及ExtTextOut函数钩子
////以下是为获取ListView内容所用的各过程///////////////////////// remove
function InstallListviewHook: boolean; //安装钩子,执行端启动时安装
function UninstallListviewHook: boolean; //卸载钩子,执行端关闭时卸载 procedure OnItemInsert(var Msg: TMessage); message WM_ItemInsert;
procedure OnItemSetItem(var Msg: TMessage); message WM_ItemSetItem;
procedure OnItemSetItemText(var Msg: TMessage); message WM_ItemSetItemText; procedure MsgExtTextout(var msg: TMessage); message WM_TEXTHOOK_EXCEPTION + 1;
procedure MsgTextout(var msg: TMessage); message WM_TEXTHOOK_EXCEPTION + 2;
procedure MsgCMPDC(var msg: TMessage); message WM_TEXTHOOK_EXCEPTION + 3; procedure ShowProberText(nCols: integer);
procedure ShowReturnText();
procedure ShowFlexHandle(sFlexHandle: string);end;
{ 交易系统模块输出函数类型}
type TIsStartUpSuccess = function(zl: TZLRecord): Boolean; stdcall;
TCloseSystem = procedure; stdcall;
TTradeBuyFunc = function(zl: TZLRecord): Boolean; stdcall; //买函数
TTradeSellFunc = function(zl: TZLRecord): Boolean; stdcall; //卖函数
TTradeChedanFunc = function(zl: TZLRecord): Boolean; stdcall; //撤单函数
TTradeQueryFundsFunc = function(zl: TZLRecord): Boolean; stdcall; //查询余额函数
TTradeQueryStockFunc = function(zl: TZLRecord): Boolean; stdcall; //查询余股函数
TTradeQueryOrderFunc = function(zl: TZLRecord): Boolean; stdcall; //成交查询函数
//////定义当前交易系统类型记录////////////////////
TCurrSys= record
hCurr : THandle;
SysName : string;
IsStartUpSuccess : TIsStartUpSuccess;
CloseSystem : TCloseSystem;
TradeBuyFunc : TTradeBuyFunc;
TradeSellFunc : TTradeSellFunc;
TradeChedanFunc : TTradeChedanFunc;
TradeQueryFundsFunc : TTradeQueryFundsFunc;
TradeQueryStockFunc : TTradeQueryStockFunc;
TradeQueryOrderFunc : TTradeQueryOrderFunc;
end;var
frmExecute: TfrmExecute;
CurrSys: TCurrSys;
sIPAddrCtrl : String;//控制端IP地址
g_sTrmnID : String;//本执行端序号{$IFDEF Debug}
LogFile: TextFile;
{$ENDIF}// g_sck: TClientSocket;
ZLTable: TZLData; //指令缓存表
ZxTable: TPerformTable; //指令执行纪录表
WaitForCount: DWORD; //内部网络断开计时
MsgStruct: ^CWPSTRUCT;
bCloseProgram: boolean; //是否关闭应用程序 bPriorZlSuccess: boolean; //上一条指令执行成功与否
sLVContent: array of array of string; //所取到的ListView的内容,每一行的内容为List中的一行值,
//在取ListView内容之前,须将它清空
str: string;
slTextOut, slXTextOut: TStringList; //TextOut、ExtTextOut函数钩子得到的字符串
function ListviewHookProc(iCode: Integer; WParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; far; //主程序用
///////////////////////////////////////////////////////////////////////
//procedure CloseAll; //关闭所有系统
procedure ParseCommand(sCommand: string); //分解命令字符串的各部分,并分析其有效性
implementationuses SysSetup, GridClass, Dll16, unitGlobal, unitWinFunc;
{$R *.DFM}//////////////////////////沟子过程开始//////////////////////////////////////
procedure TfrmExecute.BeginProbe(TargetHandle: THandle); //对目标窗口安装TextOut及ExtTextOut函数钩子
begin
slXTextOut.Clear;
slTextOut.Clear;
if bProbeInstalled then EndProbe;
SetDlgHandle16(Self.Handle);
SetTargetHandle16(TargetHandle);
if not bProbeInstalled then begin
InstallProbe16;
bProbeInstalled := True;
end;end;procedure TfrmExecute.EndProbe; //卸载TextOut及ExtTextOut函数钩子
begin
if bProbeInstalled then UNInstallProbe16;
bProbeInstalled := False;
end;procedure TfrmExecute.MsgExtTextout(var msg: TMessage);
begin
if msg.WParam = 0 then Str := '';
if msg.LParam = 0 then slXTextOut.Add(str)
else str := str + chr(Byte(msg.LParam));
end;procedure TfrmExecute.MsgTextout(var msg: TMessage);
begin
if msg.WParam = 0 then Str := '';
if msg.LParam = 0 then slTextOut.Add(str)
else str := str + chr(Byte(msg.LParam));
end;function CMPDC(DC1, DC2: HWND): Boolean;
var
C1: HDC;
begin
C1 := WOWHandle32(DC1, 4);
Result := WindowFromDC(C1) = DC2;
end;
procedure TfrmExecute.MsgCMPDC(var msg: TMessage);
var
a: Boolean;
begin
a := CMPDC(msg.wParam, msg.lParam);
msg.Result := Integer(a);
end;
//安装钩子,执行端启动时安装////////////////////////////////////
function TfrmExecute.InstallListviewHook: boolean;
begin
Result := False;
if g_hHookProc <> 0 then Exit; //如果钩子已安装则退出
g_hHookProc := SetWindowsHookEx(WH_CALLWNDPROC, @ListviewHookProc, g_hinstApp, 0); //装钩子
Result := g_hHookProc <> 0; //返回钩子是否安装成功
end;//卸载钩子,执行端关闭时卸载//////////////////////////
function TfrmExecute.UninstallListviewHook: boolean;
begin
if g_hHookProc <> 0 then
if UnhookWindowshookEx(g_hHookProc) then g_hHookProc := 0; //卸载钩子
Result := g_hHookProc = 0;
end;////钩子处理过程/////////////////////
function ListviewHookProc(iCode: Integer; WParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
var
h: HWND;
begin
if iCode >= 0 then begin
MsgStruct := pointer(lParam);
h := Windows.FindWindow('TfrmExecute', '交易代理');
case MsgStruct^.message of
LVM_INSERTITEM: begin //如果是ListView中增加一个Item,则
SendMessage(h, WM_ItemInsert, MsgStruct^.wParam, MsgStruct^.lParam); //发送WM_ItemInsert消息
end;
LVM_SETITEM: begin //如果是给ListView中某一子Item赋值,则
SendMessage(h, WM_ItemSetItem, MsgStruct^.wParam, MsgStruct^.lParam); //发送WM_ItemSetItem消息
end;
LVM_SETITEMTEXT: begin //如果是给ListView中某一子Item赋值,则
SendMessage(h, WM_ItemSetItemText, MsgStruct^.wParam, MsgStruct^.lParam); //发送WM_ItemSetItemText消息
end;
end;
end;
Result := CallNextHookEx(g_hHookProc, iCode, wParam, lParam);
end;///处理WM_ItemInsert消息//////////////////////////////
procedure TfrmExecute.OnItemInsert(var Msg: TMessage);
var
meminfo: MEMORY_BASIC_INFORMATION;
dwPro: DWORD;
dwOldProtect, dwOldProtect2: DWord;
aitem: LV_ITEM;
aCount: Cardinal;
tmpItemText: array[0..254] of Char; //临时保存ListView的item的值
hProc: THandle; //包含ListView的进程的句柄
begin
if g_hProcessId = 0 then exit;
hProc := OpenProcess(PROCESS_ALL_ACCESS, true, g_hProcessId); //得到进程句柄,其中ProcessId在启动盛润或精信时赋值
Fillchar(memInfo, sizeof(MEMORY_BASIC_INFORMATION), $0); //置初值
dwPro := VirtualQueryEx(hProc, pointer(Msg.LParam), memInfo, sizeof(MEMORY_BASIC_INFORMATION));
if dwPro <> sizeof(MEMORY_BASIC_INFORMATION) then exit;
if not VirtualProtectEx(hProc, pointer(Msg.LParam), sizeof(LV_ITEM), PAGE_EXECUTE_READ, @dwOldProtect) then exit;
if not ReadProcessMemory(hProc, pointer(Msg.LParam), @aitem, sizeof(LV_ITEM), aCount) then exit;
if not VirtualProtectEx(hProc, pointer(Msg.LParam), sizeof(LV_ITEM), dwOldProtect, @dwOldProtect2) then exit;
dwPro := VirtualQueryEx(hProc, (aitem.pszText), memInfo, sizeof(MEMORY_BASIC_INFORMATION));
if dwPro <> sizeof(MEMORY_BASIC_INFORMATION) then exit;
if not VirtualProtectEx(hProc, (aitem.pszText), 255, PAGE_EXECUTE_READ, @dwOldProtect) then exit;
if not ReadProcessMemory(hProc, (aitem.pszText), @tmpItemText, 255, aCount) then exit;
if Length(sLVContent) <= 0 then //如果接受数组长度小于等于0(表示要增加的是ListView中的第一个Item),则
SetLength(sLVContent, 1) //给接受数组设长度1
else if aitem.iItem > Length(sLVContent) - 1 then //如果要增加的Item的索引值大于接受数组的长度,则
SetLength(sLVContent, aitem.iItem + 1); //接受数组长度加1
SetLength(sLVContent[aitem.iItem], 1);
sLVContent[aitem.iItem, 0] := tmpItemText; //将Item的文本值保存下来
VirtualProtectEx(hProc, (aitem.pszText), 255, dwOldProtect, @dwOldProtect2);
end;///处理WM_ItemSetItem消息//////////////////////////////
procedure TfrmExecute.OnItemSetItem(var Msg: TMessage);
var
meminfo: MEMORY_BASIC_INFORMATION;
dwPro: DWORD;
dwOldProtect, dwOldProtect2: DWord;
aitem: LV_ITEM;
tmp1, tmp2, tmp3: integer;
aCount: Cardinal;
tmpItemText: array[0..254] of Char; //临时保存ListView的item的值
hProc: THandle; //包含ListView的进程的句柄
begin
if g_hProcessId = 0 then exit;
hProc := OpenProcess(PROCESS_ALL_ACCESS, true, g_hProcessId); //得到进程句柄,其中ProcessId在启动盛润或精信时赋值
Fillchar(memInfo, sizeof(MEMORY_BASIC_INFORMATION), $0); //置初值
dwPro := VirtualQueryEx(hProc, pointer(Msg.LParam), memInfo, sizeof(MEMORY_BASIC_INFORMATION));
if dwPro <> sizeof(MEMORY_BASIC_INFORMATION) then exit;
if not VirtualProtectEx(hProc, pointer(Msg.LParam), sizeof(LV_ITEM), PAGE_EXECUTE_READ, @dwOldProtect) then exit;
if not ReadProcessMemory(hProc, pointer(Msg.LParam), @aitem, sizeof(LV_ITEM), aCount) then exit;
if not VirtualProtectEx(hProc, pointer(Msg.LParam), sizeof(LV_ITEM), dwOldProtect, @dwOldProtect2) then exit;
dwPro := VirtualQueryEx(hProc, (aitem.pszText), memInfo, sizeof(MEMORY_BASIC_INFORMATION));
if dwPro <> sizeof(MEMORY_BASIC_INFORMATION) then exit;
if not VirtualProtectEx(hProc, (aitem.pszText), 255, PAGE_EXECUTE_READ, @dwOldProtect) then exit;
if not ReadProcessMemory(hProc, (aitem.pszText), @tmpItemText, 255, aCount) then exit;
tmp1 := aitem.iSubItem;
tmp2 := aitem.iItem;
tmp3 := Length(sLVContent[tmp2]) - 1;
if tmp1 > tmp3 then //如果要赋值的子项的索引值大于接受数组中第几行的长度,则
SetLength(sLVContent[tmp2], tmp1 + 1); //按受数组该行的长度加1
sLVContent[tmp2, tmp1] := tmpItemText; //保存该子项的文本值
VirtualProtectEx(hProc, (aitem.pszText), 255, dwOldProtect, @dwOldProtect2);
end;///处理WM_ItemSetItemText消息//////////////////////////////
procedure TfrmExecute.OnItemSetItemText(var Msg: TMessage);
var
meminfo: MEMORY_BASIC_INFORMATION;
dwPro: DWORD;
dwOldProtect, dwOldProtect2: DWord;
aitem: LV_ITEM;
ItemIndex: integer;
tmp1, tmp2, tmp3: integer;
aCount: Cardinal;
tmpItemText: array[0..254] of Char; //临时保存ListView的item的值
hProc: THandle; //包含ListView的进程的句柄
begin
if g_hProcessId = 0 then exit;
ItemIndex := Msg.WParam;
hProc := OpenProcess(PROCESS_ALL_ACCESS, true, g_hProcessId); //得到进程句柄,其中ProcessId在启动盛润或精信时赋值
Fillchar(memInfo, sizeof(MEMORY_BASIC_INFORMATION), $0); //置初值
dwPro := VirtualQueryEx(hProc, pointer(Msg.LParam), memInfo, sizeof(MEMORY_BASIC_INFORMATION));
if dwPro <> sizeof(MEMORY_BASIC_INFORMATION) then exit;
if not VirtualProtectEx(hProc, pointer(Msg.LParam), sizeof(LV_ITEM), PAGE_EXECUTE_READ, @dwOldProtect) then exit;
if not ReadProcessMemory(hProc, pointer(Msg.LParam), @aitem, sizeof(LV_ITEM), aCount) then exit;
if not VirtualProtectEx(hProc, pointer(Msg.LParam), sizeof(LV_ITEM), dwOldProtect, @dwOldProtect2) then exit;
dwPro := VirtualQueryEx(hProc, (aitem.pszText), memInfo, sizeof(MEMORY_BASIC_INFORMATION));
if dwPro <> sizeof(MEMORY_BASIC_INFORMATION) then exit;
if not VirtualProtectEx(hProc, (aitem.pszText), 255, PAGE_EXECUTE_READ, @dwOldProtect) then exit;
if not ReadProcessMemory(hProc, (aitem.pszText), @tmpItemText, 255, aCount) then exit;
tmp1 := aitem.iSubItem;
tmp2 := ItemIndex;
tmp3 := Length(sLVContent[tmp2]) - 1;
if tmp1 > tmp3 then //如果要赋值的子项的索引值大于接受数组中第几行的长度,则
SetLength(sLVContent[tmp2], tmp1 + 1); //按受数组该行的长度加1
sLVContent[ItemIndex, tmp1] := tmpItemText; //保存该子项的文本值
VirtualProtectEx(hProc, (aitem.pszText), 255, dwOldProtect, @dwOldProtect2);
end;
///////////////////////////////////////沟子过程尾///////////////////////////////////返回控制端过程
procedure TfrmExecute.Info2Ctrlr(sCode, sAcctName, sStatus, sCnttCode, sNum, sPrice: string);
var
s: string;
begin
s := g_sTrmnID + '@@' + sCode + '@@' + sAcctName + '@@' + sStatus + '@@' +
sCnttCode + '@@' + sNum + '@@' + sPrice;
if not (sAcctName = ' ') then g_slRet2Ctrl.Add(s);
s := 'start' + s + 'end';
if Assigned(g_sck) and g_sck.Active then g_sck.Socket.SendText(s);
end;procedure TfrmExecute.UpdateConnectionIndicator(bConnected: boolean);
begin
if bConnected then begin
lblCnn.Caption := '已连通';
lblCnn.Color := clBlack;
lblCnn.Font.Color := clRed;
aniGlobal.Active := True;
end
else begin
lblCnn.Caption := '未连通';
lblCnn.Font.Color := clBlue;
lblCnn.Color := clRed;
aniGlobal.Active := False;
end;
end;procedure TfrmExecute.ClientSocketError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
ErrorCode := 0;
end;procedure TfrmExecute.CreateSocketConnection();
begin
try
if Assigned(g_sck) and g_sck.Active then Exit;
g_sck.Free;
g_sck := nil;
g_sck := TClientSocket.Create(Application);
g_sck.Port := 23658;
g_sck.OnConnect := ClientSocketConnect;
g_sck.OnRead := ClientSocketRead;
g_sck.OnError := ClientSocketError;
g_sck.Address := sIPAddrCtrl;
g_sck.Active := True;
finally
end;
end;procedure TfrmExecute.ClientSocketConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
//如果内部网络断开,当Socket再次连上时,发送连通消息,以正确反映执行端的连接状态
Info2Ctrlr(_, _, 'report', _, _, _);
end;procedure TfrmExecute.tmConnectTimer(Sender: TObject);
begin
if g_nNoAnswerCounter > 6 then begin
CreateSocketConnection();
g_bNetConnected := False;
end;
UpdateConnectionIndicator(g_bNetConnected);
Inc(g_nNoAnswerCounter);
try
Info2Ctrlr(_, _, 'connect', 'adsl', _, _);
finally
end;
end;procedure TfrmExecute.ClientSocketRead(Sender: TObject; Socket: TCustomWinSocket);
var
s: string; //控制端传来的操作命令字符串
begin
s := Socket.ReceiveText; //接收控制端传来的操作命令字符串
if s = 'answer' then begin //如果收到的是对询问的回应信息,则
g_nNoAnswerCounter := 0;
g_bNetConnected := true;
exit; //退出
end;
if s = 'exit' then begin //如果收到的是'退出'指令,则
bCloseProgram := True;
Application.Terminate; //终止执行端程序
exit; //退出
end;
ParseCommand(s); //对指令串进行解析
end;//分解命令字符串的各部分,并分析其有效性
procedure ParseCommand(sCommand: string);
const
nNUM_DELI = 13 + 1; //命令字符串中'@@'的个数
var
i, nDeli, len, nCommand: Integer;
StartPos, EndPos: Integer;
sCmdArray: array of string;
sCmd, sTmpCmd: string;
sZLCode, sOpNumber, sSystemNo, sClientNo: string;
tmpZhName: string;
nLocDeli: array[1..nNUM_DELI] of Integer;
zlRcvStatement: TZLRecord;
begin
sTmpCmd := Trim(sCommand);
SetLength(sCmdArray, 0);
while True do begin
StartPos := Pos('start', sTmpCmd);
if StartPos <= 0 then break; //对该指令串不作处理
EndPos := Pos('end', sTmpCmd);
if EndPos <= 0 then break; //对该指令串不作处理
if EndPos <= StartPos then break; //对该指令串不作处理
SetLength(sCmdArray, Length(sCmdArray) + 1);
sCmdArray[Length(sCmdArray) - 1] := Copy(sTmpCmd, StartPos + 5, EndPos - StartPos - 5);
Delete(sTmpCmd, 1, EndPos + 2);
end;
for nCommand := 0 to Length(sCmdArray) - 1 do begin
sCmd := sCmdArray[nCommand];
len := Length(sCmd);
nDeli := 0;
//取得命令字串中分隔符的位置及个数
i := 1;
while i <= len do begin
if (sCmd[i] = '@') and (sCmd[i + 1] = '@') then begin
inc(nDeli);
if nDeli <= nNUM_DELI then nLocDeli[nDeli] := i;
inc(i);
end;
inc(i);
end;
if nDeli <> nNUM_DELI then begin //如果分隔符个数不等于指定数,则
frmExecute.Info2Ctrlr(sCmd, _, 'invalid', _, _, _);
Continue;
end;
sZLCode := LowerCase(Trim(Copy(sCmd, 1, nLocDeli[1] - 1)));
//从命令字串中截取指令编码部分
if sZLCode = '' then sZLCode := ' ';
sSystemNo := LowerCase(Trim(Copy(sCmd, nLocDeli[2] + 2, nLocDeli[3] - nLocDeli[2] - 2))); //从命令字串中截取系统编号部分
sClientNo := Trim(Copy(sCmd, nLocDeli[5] + 2, nLocDeli[6] - nLocDeli[5] - 2));
tmpZhName := Trim(Copy(sCmd, nLocDeli[12] + 2, nLocDeli[13] - nLocDeli[12] - 2)); //取得帐户名
if (sSystemNo <> 'jingxin') and (sSystemNo <> 'guotong')
and (sSystemNo <> 'julin') and (sSystemNo <> 'pa18') and (sSystemNo <> 'minfa')
and (sSystemNo <> 'gtja') and (sSystemNo <> 'feihu') and (sSystemNo <> 'tqzq')
and (sSystemNo <> 'haitong') and (sSystemNo <> 'guangfa') and (sSystemNo <> 'guoxin')
and (sSystemNo <> 'feihu') then begin
//qj 待定 //如果命令字串中要求的交易系统软件终端未安装则
frmExecute.Info2Ctrlr(sZLCode, tmpZhName, 'invalid', _, _, _);
Continue;
end;
sOpNumber := LowerCase(Trim(Copy(sCmd, nLocDeli[7] + 2, nLocDeli[8] - nLocDeli[7] - 2))); //从命令字串中截取操作编号部分 //对命令字串中的操作编码分析,判断是否为已定义的操作编码之一
if (sOpNumber <> 'buy') and (sOpNumber <> 'sell') and (sOpNumber <> 'chedan')
and (sOpNumber <> 'yecx') and (sOpNumber <> 'ygcx') and (sOpNumber <> 'cjcx') then begin //如果不是已定义的操作编码则退出
frmExecute.Info2Ctrlr(sZLCode, tmpZhName, 'invalid', _, _, _);
Continue;
end;
frmExecute.Info2Ctrlr(sZLCode, tmpZhName, 'valid', _, _, _);
//向控制端发送合法信息 //指令串合法,将各部分分解出来,赋予指令纪录,并写入指令缓存表
with zlRcvStatement do begin
StrPCopy(ZLCode, sZLCode);
try
Priority := strtoint(Trim(Copy(sCmd, nLocDeli[1] + 2, nLocDeli[2] - nLocDeli[1] - 2)));
except
Priority := 3; //默认3
end;
StrPCopy(SystemNo, sSystemNo);
StrPCopy(YuanJianNo, Trim(Copy(sCmd, nLocDeli[3] + 2, nLocDeli[4] - nLocDeli[3] - 2)));
StrPCopy(YuanJianPassword, Trim(Copy(sCmd, nLocDeli[4] + 2, nLocDeli[5] - nLocDeli[4] - 2))); StrPCopy(GuDongCode, sClientNo);
///////////盛润金地营业部的深市股东代码长度为10位,需要在传过来的股东代码前加'02'/////////////////////
if (StockJobber = '国泰金地') and (Length(StrPas(GuDongCode)) = 8) then
StrPCopy(GuDongCode, '02' + StrPas(GuDongCode)); StrPCopy(GuDongPassword, Trim(Copy(sCmd, nLocDeli[6] + 2, nLocDeli[7] - nLocDeli[6] - 2)));
StrPCopy(CaoZuoNo, sOpNumber);
StrPCopy(StockCode, Trim(Copy(sCmd, nLocDeli[8] + 2, nLocDeli[9] - nLocDeli[8] - 2)));
StrPCopy(StockCount, Trim(Copy(sCmd, nLocDeli[9] + 2, nLocDeli[10] - nLocDeli[9] - 2)));
StrPCopy(StockPrice, Trim(Copy(sCmd, nLocDeli[10] + 2, nLocDeli[11] - nLocDeli[10] - 2)));
StrPCopy(StockJobber, Trim(Copy(sCmd, nLocDeli[11] + 2, nLocDeli[12] - nLocDeli[11] - 2)));
StrPCopy(AccountName, tmpZhName); //////////////////////////////////////////////////////////////////////////////////////////////////////
PerformTime := Time + StrToInt(Trim(Copy(sCmd, nLocDeli[13] + 2, nLocDeli[14] - nLocDeli[13] - 2))) / (24 * 60 * 60);
StrPCopy(StockKind, Trim(Copy(sCmd, nLocDeli[14] + 2, Length(sCmd) - nLocDeli[13] - 1)));
end;
ZLTable.AppendNewRecord(zlRcvStatement); //写入指令缓存表
with frmExecute.sgrdTask, zlRcvStatement do begin
if Cells[5, 1] <> '' then RowCount := RowCount + 1;
Cells[0, RowCount - 1] := StrPas(ZLCode);
Cells[1, RowCount - 1] := inttostr(Priority);
Cells[2, RowCount - 1] := StrPas(SystemNo);
Cells[3, RowCount - 1] := StrPas(AccountName);
Cells[4, RowCount - 1] := StrPas(GuDongCode);
Cells[5, RowCount - 1] := StrPas(CaoZuoNo);
Cells[6, RowCount - 1] := StrPas(StockCode);
Cells[7, RowCount - 1] := StrPas(StockCount);
Cells[8, RowCount - 1] := StrPas(StockPrice);
Cells[9, RowCount - 1] := StrPas(StockJobber);
Cells[10, RowCount - 1] := TimeToStr(Time);
end;
end;
end;
//在创建窗体的时候,初始化系统参数//////////////////////////////////////
procedure TfrmExecute.FormCreate(Sender: TObject);
var
GridTable: TGridClass;
SetupIni: TIniFile;
GridSetup: ReturnRecord;
i: integer;
FilePath: string;
zlRcv: TZLRecord;
begin
btnStop.Enabled := False;
btnStartUp.Enabled := True;
btnExit.Enabled := True;
btnSetup.Enabled := True;
g_bNetConnected := false; lblFlex.Caption := '';
frmExecute.Caption := '交易代理';{$IFDEF Debug}
AssignFile(LogFile, 'Debug.log');
{$ENDIF} SetupIni := TIniFile.Create(ExtractFilePath(Application.ExeName) + '\' + 'syssetup.ini');
// ShenYunAppname := SetupIni.ReadString('AppPath', 'ShenYunAppname', '');
// JingXinAppname := SetupIni.ReadString('AppPath', 'JingXinAppname', '');
// Feihu :=SetupIni.ReadString('AppPath' , 'Feihu' ,''); //qj
//GuoTong := SetupIni.ReadString('AppPath', 'GuoTong', '');
// JuLin := SetupIni.ReadString('AppPath', 'JuLin', '');
// MinFa := SetupIni.ReadString('AppPath', 'MinFa', '');
// PingAnAppname := SetupIni.ReadString('AppPath', 'PingAnAppname', '');
// GuangFaAppname := SetupIni.ReadString('AppPath', 'GuangFaAppname', '');
// sGFa := SetupIni.ReadString('AppPath', 'GFa', '');
// sHait := SetupIni.ReadString('AppPath', 'Hait', '');
// guoxin := SetupIni.ReadString('AppPath', 'guoxin', '');
// sPA18 := SetupIni.ReadString('AppPath', 'PA18', '');
// sTequzq := SetupIni.ReadString('AppPath', 'Tequzq', ''); sIPAddrCtrl := SetupIni.ReadString('WinSocket', 'IPAddrCtrl', '127.0.0.1');
g_sTrmnID := SetupIni.ReadString('WinSocket', 'TrmnID', '1'); //如未设置,则默认为第一执行端
SetupIni.Free;
lblTerminalID.Caption := g_sTrmnID; //变量赋初始值
bCloseProgram := False;
g_hProcessId := 0;
//SetLength(sLVContent, 0); //对保存接收指令和已执行完指令的StringGrid初始化
GridTable := TGridClass.Create(ExtractFilePath(Application.ExeName) + '\' + 'GridSetup.dat');
GridTable.ReadColWidth(0, GridSetup);
if GridSetup.ColsRead > 0 then
with sgrdTask do begin
for i := 0 to Min(GridSetup.ColsRead, ColCount) - 1 do ColWidths[i] := GridSetup.ColsWidth[i];
end;
GridTable.ReadColWidth(1, GridSetup);
GridTable.ReadColWidth(2, GridSetup);
if GridSetup.ColsRead > 0 then
with sgrdXcuting do begin
for i := 0 to Min(GridSetup.ColsRead, ColCount) - 1 do ColWidths[i] := GridSetup.ColsWidth[i];
end;
GridTable.ReadColWidth(3, GridSetup);
GridTable.Free; with sgrdTask do begin
Cells[0, 0] := '指令编码';
Cells[1, 0] := '优先权';
Cells[2, 0] := '系统编号';
Cells[3, 0] := '帐户名称';
Cells[4, 0] := '股东代码';
Cells[5, 0] := '操作类型';
Cells[6, 0] := '股票代码';
Cells[7, 0] := '委托股数';
Cells[8, 0] := '委托价格';
Cells[9, 0] := '证券公司';
Cells[10, 0] := '到达时间';
end; with sgrdXcuting do begin
Cells[0, 0] := '指令编码';
Cells[1, 0] := '优先权';
Cells[2, 0] := '系统编号';
Cells[3, 0] := '帐户名称';
Cells[4, 0] := '股东代码';
Cells[5, 0] := '操作类型';
Cells[6, 0] := '股票代码';
Cells[7, 0] := '委托股数';
Cells[8, 0] := '委托价格';
Cells[9, 0] := '证券公司';
end;// DisplayZxRecord;//显示指令执行纪录
nPriorTime := 0;
ZLTable := TZLData.Create(ExtractFilePath(Application.ExeName), 'ZLTable.dat'); //初始化指令缓存表类
ZxTable := TPerformTable.Create(ExtractFilePath(Application.ExeName), 'ZXTable.dat'); //初始化指令执行纪录表
//将指令表中现有纪录显示出来
with ZLTable, sgrdTask do begin
for i := 0 to RecordCount - 1 do begin
GetOneRecord(i, zlRcv);
if Cells[5, 1] <> '' then RowCount := RowCount + 1;
Cells[0, RowCount - 1] := StrPas(zlRcv.ZLCode);
Cells[1, RowCount - 1] := inttostr(zlRcv.Priority);
Cells[2, RowCount - 1] := StrPas(zlRcv.SystemNo);
Cells[3, RowCount - 1] := StrPas(zlRcv.AccountName);
Cells[4, RowCount - 1] := StrPas(zlRcv.GuDongCode);
Cells[5, RowCount - 1] := StrPas(zlRcv.CaoZuoNo);
Cells[6, RowCount - 1] := StrPas(zlRcv.StockCode);
Cells[7, RowCount - 1] := StrPas(zlRcv.StockCount);
Cells[8, RowCount - 1] := StrPas(zlRcv.StockPrice);
Cells[9, RowCount - 1] := StrPas(zlRcv.StockJobber);
Cells[10, RowCount - 1] := '';
end;
if RecordCount > 0 then btnDelTask.Enabled := True;
end;// g_RetMsg := TReturnMsg.Create(ExtractFilePath(Application.ExeName), 'ReturnMsg.dat'); //初始化指令缓存表类
//三个Animate载入文件
FilePath := ExtractFilePath(Application.ExeName);
aniDigital.FileName := FilePath + '\' + 'Count24.avi';
aniGlobal.FileName := FilePath + '\' + 'globe.avi'; LoadDll16;
bProbeInstalled := False;
slTextOut := TStringList.Create;
slXTextOut := TStringList.Create;
end;procedure TfrmExecute.btnStartUpClick(Sender: TObject);
var
zl: TZLRecord; //将要执行的指令
i, nSec, nOpCode: integer;
rec: TPerformRecord;
begin
lstRet.Clear;
lstGet.Clear;
lblFlex.Caption := '';
tmConnect.Enabled := True;
btnSetup.Enabled := false;
btnStartUp.Enabled := False;
btnStartUp.default := False;
btnStop.Enabled := True;
btnStop.default := True;
g_bNetConnected := true;
g_bButtonPushed := True; CreateSocketConnection();
bCloseProgram := False;
while not bCloseProgram do begin
UpdateConnectionIndicator(g_bNetConnected);
if g_bCurrTaskDeleted then begin
with sgrdTask do begin
for i := 2 to RowCount - 1 do Rows[i - 1] := Rows[i];
if RowCount > 2 then RowCount := RowCount - 1
else Rows[1].Clear;
end;
end;
Application.HandleMessage;
if nPriorTime > 0 then begin
nSec := Ceil((GetTickCount - nPriorTime) / 1000); //得到上一指令执行的秒数 nOpCode := 0;
if (zlPrior.CaoZuoNo = 'buy') then nOpCode := 1
else if (zlPrior.CaoZuoNo = 'sell') then nOpCode := 2
else if (zlPrior.CaoZuoNo = 'chedan') then nOpCode := 3
else if (zlPrior.CaoZuoNo = 'cjcx') then nOpCode := 4
else if (zlPrior.CaoZuoNo = 'yecx') then nOpCode := 5
else if (zlPrior.CaoZuoNo = 'ygcx') then nOpCode := 6;
if nOpCode > 0 then begin
g_slRet2Ctrl.Clear;
ShowReturnText();
rec.Date := Date;
rec.SystemNo := zlPrior.SystemNo;
rec.CaoZuoCode := nOpCode;
rec.CaoZuoName := sOPR_NAME[nOpCode];
rec.SuccessFail := bPriorZlSuccess;
rec.HaoShi := nSec;
ZxTable.AppendRecord(rec);
ZxTable.Post;
end;
end;
if ZLTable.RecordCount > 0 then begin
ZLTable.GetFirstTask(zl); //得到优先权最高的那条指令
g_bCurrTaskDeleted := false;
end;
if (ZLTable.RecordCount <= 0) or (zl.PerformTime > Time) then begin //如果指令缓存表为空,则不作处理,开始下一次循环
with sgrdXcuting do begin //如果显示正在执行的指令的网格不为空,则清空
if Cells[5, 1] <> '' then for i := 0 to ColCount - 1 do Cells[i, 1] := '';
end;
if aniDigital.Active then aniDigital.Active := False; //停止转动显示牌
zlPrior.CaoZuoNo := '';
nPriorTime := 0;
Continue;
end;
Application.HandleMessage;
with sgrdXcuting do begin
Cells[0, 1] := StrPas(zl.ZLCode);
Cells[1, 1] := inttostr(zl.Priority);
Cells[2, 1] := StrPas(zl.SystemNo);
Cells[3, 1] := StrPas(zl.AccountName);
Cells[4, 1] := StrPas(zl.GuDongCode);
Cells[5, 1] := StrPas(zl.CaoZuoNo);
Cells[6, 1] := StrPas(zl.StockCode);
Cells[7, 1] := StrPas(zl.StockCount);
Cells[8, 1] := StrPas(zl.StockPrice);
Cells[9, 1] := StrPas(zl.StockJobber);
end;
nPriorTime := GetTickCount;
bPriorZlSuccess := False;
if not aniDigital.Active then aniDigital.Active := True;
zlPrior := zl;
/////////////调用Dll///////////////
{ Load the DLL and get all the procedure addresses. } if CurrSys.SysName <>zl.SystemNo then
begin
if Assigned(CurrSys.CloseSystem) then
CurrSys.CloseSystem;
FreeLibrary (CurrSys.hCurr);
CurrSys.SysName:=zl.SystemNo ;
CurrSys.hCurr := LoadLibrary(PChar('C:\DLLS\'+CurrSys.SysName+'.'+'dll'));
CurrSys.IsStartUpSuccess:=(GetProcAddress(CurrSys.hCurr,'IsStartUpSuccess'));
CurrSys.TradeBuyFunc:= (GetProcAddress(CurrSys.hCurr, 'TradeBuyFunc'));
CurrSys.TradeSellFunc:=(GetProcAddress(CurrSys.hCurr, 'TradeSellFunc'));
CurrSys.TradeChedanFunc:=(GetProcAddress(CurrSys.hCurr, 'TradeChedanFunc'));
CurrSys.TradeQueryStockFunc:=(GetProcAddress(CurrSys.hCurr, 'TradeQueryStockFunc'));
CurrSys.TradeQueryFundsFunc:=(GetProcAddress(CurrSys.hCurr, Pointer(3)));
CurrSys.TradeQueryOrderFunc:=(GetProcAddress(CurrSys.hCurr, 'TradeQueryOrderFunc'));
end;
CurrSys.IsStartUpSuccess(zl) ;
if zl.CaoZuoNo ='buy' then begin
if zl.SystemNo =CurrSys.SysName then
CurrSys.TradeBuyFunc(zl);
end
else if zl.CaoZuoNO='sell' then begin
if zl.SystemNo =CurrSys.SysName then
CurrSys.TradeSellFunc(zl);
end
else if zl.CaoZuoNo='chedan' then begin
if zl.SystemNo =CurrSys.SysName then
CurrSys.TradeChedanFunc(zl);
end
else if zl.CaoZuoNo='yecx' then begin
if zl.SystemNo =CurrSys.SysName then
CurrSys.TradeQueryFundsFunc(zl);
end
else if zl.CaoZuoNo='ygcx' then begin
if zl.SystemNo =CurrSys.SysName then
CurrSys.TradeQueryStockFunc(zl);
end
else if zl.CaoZuoNo='cjcx' then begin
if zl.SystemNo =CurrSys.SysName then
CurrSys.TradeQueryOrderFunc(zl);
end;
end; /////////////////////////////////////////////////////////////////////// { if (zl.CaoZuoNo = 'buy') then begin
if zl.SystemNo = 'HEXIN_FEIHU.DLL' then hexinFeihu.TradeBuyFunc(zl); end else if zl.CaoZuoNo = 'sell' then begin
if zl.SystemNo ='HEXIN_FEIHU.DLL' then hexinFeihu.TradeSellFunc(zl);
end
else if zl.CaoZuoNo = 'chedan' then begin
if zl.SystemNo = 'HEXIN_FEIHU.DLL' then hexinFeihu.TradeChedanFunc(zl); end
else if zl.CaoZuoNo = 'yecx' then begin
if zl.SystemNo = 'HEXIN_FEIHU.DLL' then hexinFeihu.TradeQueryFundsFunc(zl); end
else if zl.CaoZuoNo = 'ygcx' then begin
if zl.SystemNo = 'HEXIN_FEIHU.DLL' then hexinFeihu.TradeQueryStockFunc(zl); end
else if zl.CaoZuoNo = 'cjcx' then begin
if zl.SystemNo = 'HEXIN_FEIHU.DLL' then hexinFeihu.TradeQueryOrderFunc(zl); end
else
if not g_bCurrTaskDeleted then g_bCurrTaskDeleted := ZLTable.DelFirstTask; frmExecute.ShowReturnText();
end; }
end;/////////调用系统设置界面////////////////////////////
procedure TfrmExecute.btnSetupClick(Sender: TObject);
begin
frmSysSetup := TfrmSysSetup.Create(Application);
frmSysSetup.ShowModal;
frmSysSetup.Free;
end;procedure TfrmExecute.btnLogKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = vk_F1 then
Application.HelpContext(2);
end;
procedure TfrmExecute.sgrdTaskDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
var
tmpLeft, tmpTop: integer;
tmpWidth: integer;
TextToOut: string;
begin
with Sender as TStringGrid do begin
if gdFixed in State then
Canvas.Brush.Color := clBtnFace //设固定行底色
else if (Sender = sgrdTask) and (ARow = Row) and (btnDelTask.Enabled) then
Canvas.Brush.Color := clAqua
else
Canvas.Brush.Color := Color;
Canvas.FillRect(Rect);
Canvas.Font := Font;
if ARow > 0 then
Canvas.Font.Name := 'MS Sans Serif';
TextToOut := Cells[ACol, ARow];
tmpWidth := Canvas.TextWidth(TextToOut);
while tmpWidth > (Rect.Right - Rect.Left) do begin
Delete(TextToOut, Length(TextToOut) - 1, 2);
tmpWidth := Canvas.TextWidth(TextToOut);
end;
tmpLeft := (((Rect.Right - Rect.Left) - tmpWidth) div 2) + Rect.Left;
tmpTop := (((Rect.Bottom - Rect.Top) - Canvas.TextHeight(Cells[ACol, ARow])) div 2) + Rect.Top;
Canvas.TextOut(tmpLeft, tmpTop, TextToOut);
end;
end;procedure TfrmExecute.FormClose(Sender: TObject; var Action: TCloseAction);
var
GridTable: TGridClass;
WidthToSave: array[0..128] of Word;
i: integer;
begin
bCloseProgram := True;
tmConnect.Enabled := False; GridTable := TGridClass.Create(ExtractFilePath(Application.ExeName) + '\' + 'GridSetup.dat');
with sgrdTask do begin
for i := 0 to ColCount - 1 do WidthToSave[i] := ColWidths[i];
GridTable.SaveColWidth(0, WidthToSave, ColCount);
end;
with sgrdXcuting do begin
for i := 0 to ColCount - 1 do WidthToSave[i] := ColWidths[i];
GridTable.SaveColWidth(2, WidthToSave, ColCount);
end; GridTable.Free;
// if g_bHookInstalled then g_bHookInstalled := not UninstallListviewHook; //卸载钩子
end;{
procedure TfrmExecute.btnLogClick(Sender: TObject);
begin
frmZxRecordEdit := TfrmZxRecordEdit.Create(Application);
frmZxRecordEdit.ShowModal;
frmZxRecordEdit.Free;
end;
}procedure TfrmExecute.btnDelTaskClick(Sender: TObject);
var
i: integer;
begin
ZLTable.DeleteOneRecord(sgrdTask.Row - 1);
with sgrdTask do begin
for i := 2 to RowCount - 1 do Rows[i - 1] := Rows[i];
if RowCount > 2 then RowCount := RowCount - 1
else Rows[1].Clear;
end;
if sgrdTask.Cells[5, 1] = '' then begin
btnDelTask.Enabled := False;
sgrdTask.Repaint;
end;
end;procedure TfrmExecute.sgrdTaskSelectCell(Sender: TObject; ACol,
ARow: Integer; var CanSelect: Boolean);
var
co: Integer;
begin
with TStringGrid(Sender) do
for co := 0 to ColCount - 1 do begin
Cells[co, Row] := Cells[co, Row];
Cells[co, ARow] := Cells[co, ARow];
end;
end;
procedure TfrmExecute.FormDestroy(Sender: TObject);
begin
if Assigned(ZxTable) then ZxTable.Free;
if Assigned(ZlTable) then ZLTable.Free;
end;procedure TfrmExecute.btnExitClick(Sender: TObject);
begin
Close;
Application.Terminate;
end;procedure TfrmExecute.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = VK_escape then Close;
end;procedure TfrmExecute.btnStopClick(Sender: TObject);
begin
Info2Ctrlr(_, _, 'disconnect', _, _, _);
g_bButtonPushed := False;
g_bNetConnected := false;
tmConnect.Enabled := False;
bCloseProgram := True;
btnSetup.Enabled := True;
btnStartUp.Enabled := True;
btnStartUp.Default := True;
btnStop.Enabled := False;
btnStop.Default := False;
aniDigital.Active := False; //停止转动显示牌
aniGlobal.Active := False;
// if g_bHookInstalled then g_bHookInstalled := not UninstallListviewHook; //卸载钩子
if sgrdTask.Cells[5, 1] <> '' then btnDelTask.Enabled := True;
UpdateConnectionIndicator(g_bNetConnected);
if not Assigned(g_sck) then Exit;
g_sck.Free;
g_sck := nil;
end;procedure TfrmExecute.ShowReturnText();
var
i: Integer;
begin
for i := 0 to g_slRet2Ctrl.Count - 1 do
lstRet.Items.Add(g_slRet2Ctrl.Strings[i]);
end;procedure TfrmExecute.ShowProberText(nCols: integer);
var
i, j, nRows: Integer;
s: string;
begin
lstGet.Clear;
nRows := g_slProberGet.Count div nCols;
for i := 0 to nRows - 1 do begin
s := '';
for j := 0 to nCols - 2 do begin
s := s + g_slProberGet.Strings[i * ncols + j] + ' ';
end;
lstGet.Items.Add(s);
end;
end;procedure TfrmExecute.ShowFlexHandle(sFlexHandle: string);
begin
lblFlex.Caption := 'FlexGrid句柄:' + sFlexHandle;
end;end.
[email protected]
在此先谢谢 了!
参考COM