EXE 与DLL 通信可以用句柄来通信的DLL 向主程序发送消息 var wp, lp: longint; begin wp := GlobalAddAtom(pchar(wParam)); lp := 0; if lparam <> '' then lp := GlobalAddAtom(pchar(lParam)); if pr_Systems.MainHandle > 0 then begin PostMessage(pr_Systems.MainHandle, WM_mainmessage, wp, lp); end; end//主程序接收消息 procedure WM_messageMain(var Message: TMessage); message WM_Mainmessage; var sl, index: integer; formhandle: THandle; strcommand, strcommandtext, strcommandsend, strcommandtextsend: string; commandarr: Array[0..1023] of char; // 消息命令 commandtextarr: array[0..1023] of char; // 消息内容 windhand: THandle; wp: longint; begin strcommand := ''; strcommandtext := ''; if Message.WParam <> 0 then //消息命令 begin sl := GlobalGetAtomName(Message.WParam, @commandarr, sizeof(commandarr)); GlobalDeleteAtom(Message.WParam); if sl > 0 then begin commandarr[sl] := #0; strcommand := commandarr; strcommand := lowercase(strcommand); end; end; if Message.LParam <> 0 then//消息内容体 begin sl := GlobalGetAtomName(Message.LParam, @commandtextarr, sizeof(commandtextarr)); GlobalDeleteAtom(Message.LParam); if sl > 0 then begin commandtextarr[sl] := #0; strcommandtext := commandtextarr; strcommandtext := trim(strcommandtext); end; end; if strcommand = '' then exit; if self.FIsrecordMessage then //记录消息 begin self.FMsgMainList.Append(strcommand + '=' + strcommandtext); if FMsgMainList.Count > MaxStringListCount then begin ttjpubfun.WriteToLog(FMsgMainList, TtjAppRegInfo.GetApplicationAppLogPath + 'mdiform_message_' + FormatDateTime('YYYYMMDD', Now()) + '.txt'); FMsgMainList.Clear; end; end; if strcommand = 'login' then //DLL登录 begin // formhandle = <billidend>xxxx<billiden> formhandle := strtointdef(ttjpubfun.ExtractName(strcommandtext, '0'), 0); if formhandle > 0 then begin index := self.FMDIFormList.IndexOfName(inttostr(formhandle)); if index >= 0 then FMDIFormList.Delete(index); FMDIFormList.Append(strcommandtext); end; end else if strcommand = 'logout' then //DLL退出 begin // strcommandtext = logout form handle exmple 1 formhandle := strtointdef(strcommandtext, 0); index := self.FMDIFormList.IndexOfName(inttostr(formhandle)); if index >= 0 then FMDIFormList.Delete(index); end else if strcommand = 'checksubmit' then //DLL审核提交 begin //<billiden>xxx<billiden><keyvalues>xxxxx</keyvalues> self.Postmessagetomsgclient('checksubmit', strcommandtext, True); end else if strcommand = 'checkpass' then //DLL审核同意 begin self.PostmessageTomsgclient(strcommand, strcommandtext, true); end else if strcommand = 'checkunpass' then //DLL审核不同意 begin self.PostmessageTomsgclient(strcommand, strcommandtext, True); end else if strcommand = 'checkback' then begin self.PostmessageTomsgclient(strcommand, strcommandtext, True); end else if strcommand = 'checkcancel' then begin self.PostmessageTomsgclient(strcommand, strcommandtext, True); end else if strcommand = 'checkinfo' then begin self.PostmessageTomsgclient(strcommand, strcommandtext, True); end else if strcommand = 'help' then //DLL请求打开帮助文件 begin self.openhelp(strcommandtext); end; end;//帮助文件负责解释是哪个窗体,哪个控件,好定位到相应的帮助文件 procedure THelpFile.openhelpchm(const value: string); var dllname, formname, controlname, sTopic: string; helpcontext, index: integer; query: HH_FTS_Query; popup: HH_POPUP; hh: HWND; begin dllname := TAnalysestr.ReadString(value, 'dllname', ''); formname := TAnalysestr.ReadString(value, 'formname', ''); controlname := TAnalysestr.ReadString(value, 'controlname', ''); helpcontext := strtointdef(TAnalysestr.ReadString(value, 'helpcontext', '0'), 0); sTopic := ''; if (dllname <> '') or (formname <> '') or (controlname <> '') then begin if Fadodataset_help.Locate('dllname;formname;controlname', vararrayof([dllname, formname, controlname]), []) then sTopic := Fadodataset_help.FieldByname('htmfilename').AsString else if Fadodataset_help.Locate('dllname;formname', vararrayof([dllname, formname]), []) then sTopic := Fadodataset_help.FieldByname('htmfilename').AsString else if Fadodataset_help.Locate('dllname', dllname, []) then sTopic := Fadodataset_help.FieldByname('htmfilename').AsString; end; if TAnalysestr.ReadString(value, 'query', '') <> '' then begin with query do begin cbStruct := sizeof(HH_FTS_Query); fUniCodeStrings := false; iProximity := HH_FTS_DEFAULT_PROXIMITY; fStemmedSearch := True; fExecute := True; fTitleOnly := False; pszWindow := nil; pszSearchQuery := pchar(TAnalysestr.ReadString(value, 'query', '')); end; strfullquery := TAnalysestr.ReadString(value, 'query', '');
HtmlHelpA(0, pchar(Fhelpfilename), HH_DISPLAY_SEARCH, PDWORD(@query)); hh := FindWindow('HH Parent', pchar('hrms help')); if hh <= 0 then hh := FindWindow('HH Parent', pchar('help')); if hh > 0 then begin EnumChildWindows(hh, @EnumWindowsProc, 0); end; end else if helpcontext > 0 then begin with popup do begin cbStruct := sizeof(HH_POPUP); hinst:= 0; idString := helpcontext; pszText:=nil; //pt:= pt; GetCursorPos(pt); clrForeground:=COLORREF(-1); clrBackground:=COLORREF(-1); rcMargins.Left := 0; rcMargins.Top := 0; rcMargins.Right := 25; rcMargins.Bottom := 25; pszFont:=LPCTSTR('BOLD'); end; HtmlHelpA(0, pchar(Fhelpfilename), HH_DISPLAY_TEXT_POPUP, PDWORD(@popup)); end else if sTopic <> '' then HtmlHelpA(0, pchar(Fhelpfilename), HH_DISPLAY_TOPIC, PDWORD(pchar(sTopic))) else if sTopic = '' then HtmlHelpA(0, pchar(Fhelpfilename), HH_DISPLAY_TOC, PDWORD(pchar(sTopic))) end;
2.DLL需要返回什么样的信息,EXE需要根据这些信息执行什么动作,还要不要传递给DLL
var
wp, lp: longint;
begin
wp := GlobalAddAtom(pchar(wParam));
lp := 0;
if lparam <> '' then lp := GlobalAddAtom(pchar(lParam));
if pr_Systems.MainHandle > 0 then
begin
PostMessage(pr_Systems.MainHandle, WM_mainmessage, wp, lp);
end;
end//主程序接收消息
procedure WM_messageMain(var Message: TMessage); message WM_Mainmessage;
var
sl, index: integer;
formhandle: THandle;
strcommand, strcommandtext, strcommandsend, strcommandtextsend: string;
commandarr: Array[0..1023] of char; // 消息命令
commandtextarr: array[0..1023] of char; // 消息内容
windhand: THandle;
wp: longint;
begin
strcommand := '';
strcommandtext := '';
if Message.WParam <> 0 then //消息命令
begin
sl := GlobalGetAtomName(Message.WParam, @commandarr, sizeof(commandarr));
GlobalDeleteAtom(Message.WParam);
if sl > 0 then
begin
commandarr[sl] := #0;
strcommand := commandarr;
strcommand := lowercase(strcommand);
end;
end;
if Message.LParam <> 0 then//消息内容体
begin
sl := GlobalGetAtomName(Message.LParam, @commandtextarr, sizeof(commandtextarr));
GlobalDeleteAtom(Message.LParam);
if sl > 0 then
begin
commandtextarr[sl] := #0;
strcommandtext := commandtextarr;
strcommandtext := trim(strcommandtext);
end;
end;
if strcommand = '' then exit;
if self.FIsrecordMessage then //记录消息
begin
self.FMsgMainList.Append(strcommand + '=' + strcommandtext);
if FMsgMainList.Count > MaxStringListCount then
begin
ttjpubfun.WriteToLog(FMsgMainList,
TtjAppRegInfo.GetApplicationAppLogPath + 'mdiform_message_' +
FormatDateTime('YYYYMMDD', Now()) + '.txt');
FMsgMainList.Clear;
end;
end;
if strcommand = 'login' then //DLL登录
begin // formhandle = <billidend>xxxx<billiden>
formhandle := strtointdef(ttjpubfun.ExtractName(strcommandtext, '0'), 0);
if formhandle > 0 then
begin
index := self.FMDIFormList.IndexOfName(inttostr(formhandle));
if index >= 0 then FMDIFormList.Delete(index);
FMDIFormList.Append(strcommandtext);
end;
end
else if strcommand = 'logout' then //DLL退出
begin // strcommandtext = logout form handle exmple 1
formhandle := strtointdef(strcommandtext, 0);
index := self.FMDIFormList.IndexOfName(inttostr(formhandle));
if index >= 0 then FMDIFormList.Delete(index);
end
else if strcommand = 'checksubmit' then //DLL审核提交
begin //<billiden>xxx<billiden><keyvalues>xxxxx</keyvalues>
self.Postmessagetomsgclient('checksubmit', strcommandtext, True);
end
else if strcommand = 'checkpass' then //DLL审核同意
begin
self.PostmessageTomsgclient(strcommand, strcommandtext, true);
end
else if strcommand = 'checkunpass' then //DLL审核不同意
begin
self.PostmessageTomsgclient(strcommand, strcommandtext, True);
end
else if strcommand = 'checkback' then
begin
self.PostmessageTomsgclient(strcommand, strcommandtext, True);
end
else if strcommand = 'checkcancel' then
begin
self.PostmessageTomsgclient(strcommand, strcommandtext, True);
end
else if strcommand = 'checkinfo' then
begin
self.PostmessageTomsgclient(strcommand, strcommandtext, True);
end
else if strcommand = 'help' then //DLL请求打开帮助文件
begin
self.openhelp(strcommandtext);
end;
end;//帮助文件负责解释是哪个窗体,哪个控件,好定位到相应的帮助文件
procedure THelpFile.openhelpchm(const value: string);
var
dllname, formname, controlname, sTopic: string;
helpcontext, index: integer;
query: HH_FTS_Query;
popup: HH_POPUP;
hh: HWND;
begin
dllname := TAnalysestr.ReadString(value, 'dllname', '');
formname := TAnalysestr.ReadString(value, 'formname', '');
controlname := TAnalysestr.ReadString(value, 'controlname', '');
helpcontext := strtointdef(TAnalysestr.ReadString(value, 'helpcontext', '0'), 0);
sTopic := ''; if (dllname <> '') or (formname <> '') or (controlname <> '') then
begin
if Fadodataset_help.Locate('dllname;formname;controlname', vararrayof([dllname, formname, controlname]), []) then
sTopic := Fadodataset_help.FieldByname('htmfilename').AsString
else if Fadodataset_help.Locate('dllname;formname', vararrayof([dllname, formname]), []) then
sTopic := Fadodataset_help.FieldByname('htmfilename').AsString
else if Fadodataset_help.Locate('dllname', dllname, []) then
sTopic := Fadodataset_help.FieldByname('htmfilename').AsString;
end; if TAnalysestr.ReadString(value, 'query', '') <> '' then
begin
with query do
begin
cbStruct := sizeof(HH_FTS_Query);
fUniCodeStrings := false;
iProximity := HH_FTS_DEFAULT_PROXIMITY;
fStemmedSearch := True;
fExecute := True;
fTitleOnly := False;
pszWindow := nil;
pszSearchQuery := pchar(TAnalysestr.ReadString(value, 'query', ''));
end;
strfullquery := TAnalysestr.ReadString(value, 'query', '');
HtmlHelpA(0, pchar(Fhelpfilename), HH_DISPLAY_SEARCH, PDWORD(@query)); hh := FindWindow('HH Parent', pchar('hrms help'));
if hh <= 0 then hh := FindWindow('HH Parent', pchar('help'));
if hh > 0 then
begin
EnumChildWindows(hh, @EnumWindowsProc, 0);
end;
end
else if helpcontext > 0 then
begin
with popup do
begin
cbStruct := sizeof(HH_POPUP);
hinst:= 0;
idString := helpcontext;
pszText:=nil;
//pt:= pt;
GetCursorPos(pt);
clrForeground:=COLORREF(-1);
clrBackground:=COLORREF(-1);
rcMargins.Left := 0;
rcMargins.Top := 0;
rcMargins.Right := 25;
rcMargins.Bottom := 25;
pszFont:=LPCTSTR('BOLD');
end;
HtmlHelpA(0, pchar(Fhelpfilename), HH_DISPLAY_TEXT_POPUP, PDWORD(@popup));
end
else if sTopic <> '' then
HtmlHelpA(0, pchar(Fhelpfilename), HH_DISPLAY_TOPIC, PDWORD(pchar(sTopic)))
else if sTopic = '' then
HtmlHelpA(0, pchar(Fhelpfilename), HH_DISPLAY_TOC, PDWORD(pchar(sTopic)))
end;
对于各自独立的功能模块,可封装在DLL中,传入application.handle和数据库连接_Connection
以减少主exe的大小。对于与主程序交互比较多的一般不做成dll