📄 ddeman.pas
字号:
end;
end;
function TDdeClientConv.CreateDdeConv(FHszApp: HSZ; FHszTopic: HSZ): Boolean;
var
Context: TConvContext;
begin
FillChar(Context, SizeOf(Context), 0);
with Context do
begin
cb := SizeOf(TConvConText);
iCodePage := CP_WINANSI;
end;
FConv := DdeConnect(ddeMgr.DdeInstId, FHszApp, FHszTopic, @Context);
Result := FConv <> 0;
if Result then
begin
FCnvInfo.cb := sizeof(TConvInfo);
DdeQueryConvInfo(FConv, QID_SYNC, @FCnvInfo);
DdeSetUserHandle(FConv, QID_SYNC, LongInt(Self));
end;
end;
function TDdeClientConv.StartAdvise: Boolean;
var
ItemLnk: TDdeCliItem;
i: word;
begin
Result := False;
if FConv = 0 then Exit;
i := 0;
while i < FItems.Count do
begin
ItemLnk := TDdeCliItem(FItems [i]);
if Not ItemLnk.StartAdvise then
begin
ItemLnk.Control.DdeItem := EmptyStr;
end else
Inc(i);
if i >= FItems.Count then
break;
end;
Result := True;
end;
function TDdeClientConv.ExecuteMacroLines(Cmd: TStrings; waitFlg: Boolean): Boolean;
begin
Result := False;
if (FConv = 0) or FWaitStat then Exit;
Result := ExecuteMacro(PChar(Cmd.Text), waitFlg);
end;
function TDdeClientConv.ExecuteMacro(Cmd: PChar; waitFlg: Boolean): Boolean;
var
hszCmd: HDDEData;
hdata: HDDEData;
ddeRslt: LongInt;
begin
Result := False;
if (FConv = 0) or FWaitStat then Exit;
hszCmd := DdeCreateDataHandle(ddeMgr.DdeInstId, Cmd, StrLen(Cmd) + 1,
0, 0, FDdeFmt, 0);
if hszCmd = 0 then Exit;
if waitFlg = True then FWaitStat := True;
hdata := DdeClientTransaction(Pointer(hszCmd), DWORD(-1), FConv, 0, FDdeFmt,
XTYP_EXECUTE, TIMEOUT_ASYNC, @ddeRslt);
if hdata = 0 then FWaitStat := False
else Result := True;
end;
function TDdeClientConv.PokeDataLines(const Item: string; Data: TStrings): Boolean;
begin
Result := False;
if (FConv = 0) or FWaitStat then Exit;
Result := PokeData(Item, PChar(Data.Text));
end;
function TDdeClientConv.PokeData(const Item: string; Data: PChar): Boolean;
var
hszDat: HDDEData;
hdata: HDDEData;
hszItem: HSZ;
begin
Result := False;
if (FConv = 0) or FWaitStat then Exit;
hszItem := DdeCreateStringHandle(ddeMgr.DdeInstId, PChar(Item), CP_WINANSI);
if hszItem = 0 then Exit;
hszDat := DdeCreateDataHandle (ddeMgr.DdeInstId, Data, StrLen(Data) + 1,
0, hszItem, FDdeFmt, 0);
if hszDat <> 0 then
begin
hdata := DdeClientTransaction(Pointer(hszDat), DWORD(-1), FConv, hszItem,
FDdeFmt, XTYP_POKE, TIMEOUT_ASYNC, nil);
Result := hdata <> 0;
end;
DdeFreeStringHandle (ddeMgr.DdeInstId, hszItem);
end;
function TDdeClientConv.RequestData(const Item: string): PChar;
var
hData: HDDEData;
ddeRslt: LongInt;
hItem: HSZ;
pData: Pointer;
Len: Integer;
begin
Result := nil;
if (FConv = 0) or FWaitStat then Exit;
hItem := DdeCreateStringHandle(ddeMgr.DdeInstId, PChar(Item), CP_WINANSI);
if hItem <> 0 then
begin
hData := DdeClientTransaction(nil, 0, FConv, hItem, FDdeFmt,
XTYP_REQUEST, 10000, @ddeRslt);
DdeFreeStringHandle(ddeMgr.DdeInstId, hItem);
if hData <> 0 then
try
pData := DdeAccessData(hData, @Len);
if pData <> nil then
try
Result := StrAlloc(Len + 1);
Move(pData^, Result^, len); // data is binary, may contain nulls
Result[len] := #0;
finally
DdeUnaccessData(hData);
end;
finally
DdeFreeDataHandle(hData);
end;
end;
end;
function TDdeClientConv.GetCliItemByName(const ItemName: string): TPersistent;
var
ItemLnk: TDdeCliItem;
i: word;
begin
Result := nil;
i := 0;
while i < FItems.Count do
begin
ItemLnk := TDdeCliItem(FItems[i]);
if ItemLnk.Item = ItemName then
begin
Result := ItemLnk;
Exit;
end;
Inc(i);
end;
end;
procedure TDdeClientConv.XactComplete;
begin
FWaitStat := False;
end;
procedure TDdeClientConv.SrvrDisconnect;
var
ItemLnk: TDdeCliItem;
i: word;
begin
if FConv <> 0 then Close;
FConv := 0;
i := 0;
while i < FItems.Count do
begin
ItemLnk := TDdeCliItem(FItems [i]);
ItemLnk.SrvrDisconnect;
inc(i);
end;
end;
procedure TDdeClientConv.DataChange(DdeDat: HDDEData; hszIt: HSZ);
var
ItemLnk: TDdeCliItem;
i: word;
begin
i := 0;
while i < FItems.Count do
begin
ItemLnk := TDdeCliItem(FItems [i]);
if (hszIt = 0) or (ItemLnk.HszItem = hszIt) then
begin
{ data has changed and we found a link that might be interested }
ItemLnk.StoreData(DdeDat);
end;
Inc(i);
end;
end;
function TDdeClientConv.SetLink(const Service, Topic: string): Boolean;
begin
CloseLink;
if FConnectMode = ddeAutomatic then
Result := ChangeLink(Service, Topic, '')
else begin
SetService(Service);
SetTopic(Topic);
DataChange(0,0);
Result := True;
end;
end;
procedure TDdeClientConv.SetConnectMode(NewMode: TDataMode);
begin
if FConnectMode <> NewMode then
begin
if (NewMode = ddeAutomatic) and (Length(DdeService) <> 0) and
(Length(DdeTopic) <> 0) and not OpenLink then
raise Exception.CreateRes(@SDdeNoConnect);
FConnectMode := NewMode;
end;
end;
procedure TDdeClientConv.SetFormatChars(NewFmt: Boolean);
begin
if FFormatChars <> NewFmt then
begin
FFormatChars := NewFmt;
if FConv <> 0 then DataChange(0, 0);
end;
end;
procedure TDdeClientConv.SetDdeService(const Value: string);
begin
end;
procedure TDdeClientConv.SetDdeTopic(const Value: string);
begin
end;
procedure TDdeClientConv.SetService(const Value: string);
begin
FDdeService := Value;
end;
procedure TDdeClientConv.SetTopic(const Value: string);
begin
FDdeTopic := Value;
end;
procedure TDdeClientConv.Close;
begin
if Assigned(FOnClose) then FOnClose(Self);
end;
procedure TDdeClientConv.Open;
begin
if Assigned(FOnOpen) then FOnOpen(Self);
end;
procedure TDdeClientConv.Notification(AComponent: TComponent;
Operation: TOperation);
var
ItemLnk: TDdeCliItem;
i: word;
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (FItems <> nil) then
begin
i := 0;
while i < FItems.Count do
begin
ItemLnk := TDdeCliItem(FItems [i]);
if (AComponent = ItemLnk.Control) then
ItemLnk.Control.DdeItem := EmptyStr;
if i >= FItems.Count then break;
Inc(I);
end;
end;
end;
constructor TDdeClientItem.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FLines := TStringList.Create;
end;
destructor TDdeClientItem.Destroy;
begin
FLines.Free;
inherited Destroy;
end;
procedure TDdeClientItem.SetDdeClientConv(Val: TDdeClientConv);
var
OldItem: string;
begin
if Val <> FDdeClientConv then
begin
OldItem := DdeItem;
FDdeClientItem := '';
if FDdeClientConv <> nil then
FDdeClientConv.OnDetach (Self);
FDdeClientConv := Val;
if FDdeClientConv <> nil then
begin
FDdeClientConv.FreeNotification(Self);
if Length(OldItem) <> 0 then SetDdeClientItem (OldItem);
end;
end;
end;
procedure TDdeClientItem.SetDdeClientItem(const Val: string);
begin
if FDdeClientConv <> nil then
begin
FDdeClientItem := Val;
if Not FDdeClientConv.OnSetItem (Self, Val) then
begin
if Not (csLoading in ComponentState) or
not ((FDdeClientConv.FConv = 0) and
(FDdeClientConv.ConnectMode = ddeManual)) then
FDdeClientItem := '';
end;
end
else if (csLoading in ComponentState) then
FDdeClientItem := Val;
end;
procedure TDdeClientItem.Notification(AComponent: TComponent;
Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (AComponent = FDdeClientConv) then
begin
FDdeClientConv.OnDetach (Self);
FDdeClientConv := nil;
FDdeClientItem := '';
end;
end;
procedure TDdeClientItem.OnAdvise;
begin
if csDesigning in ComponentState then
begin
if Owner.InheritsFrom (TForm) and (TForm(Owner).Designer <> nil) then
TForm(Owner).Designer.Modified;
end;
if Assigned(FOnChange) then FOnChange(Self);
end;
function TDdeClientItem.GetText: string;
begin
if FLines.Count > 0 then
Result := FLines.Strings[0]
else Result := '';
end;
procedure TDdeClientItem.SetText(const S: string);
begin
end;
procedure TDdeClientItem.SetLines(L: TStrings);
begin
end;
constructor TDdeCliItem.Create(ADS: TDdeClientConv);
begin
inherited Create;
FHszItem := 0;
FCliConv := ADS;
end;
destructor TDdeCliItem.Destroy;
begin
StopAdvise;
inherited Destroy;
end;
function TDdeCliItem.SetItem(const S: string): Boolean;
var
OldItem: string;
begin
Result := False;
OldItem := Item;
if FHszItem <> 0 then StopAdvise;
FItem := S;
FCtrl.Lines.Clear;
if (Length(Item) <> 0) then
begin
if (FCliConv.Conv <> 0) then
begin
Result := StartAdvise;
if Not Result then
FItem := '';
end
else if FCliConv.ConnectMode = ddeManual then Result := True;
end;
RefreshData;
end;
procedure TDdeCliItem.StoreData(DdeDat: HDDEData);
var
Len: Longint;
Data: string;
I: Integer;
begin
if DdeDat = 0 then
begin
RefreshData;
Exit;
end;
Data := PChar(AccessData(DdeDat, @Len));
if Data <> '' then
begin
FCtrl.Lines.Text := Data;
ReleaseData(DdeDat);
if FCliConv.FormatChars = False then
begin
for I := 1 to Length(Data) do
if (Data[I] > #0) and (Data[I] < ' ') then Data[I] := ' ';
FCtrl.Lines.Text := Data;
end;
end;
DataChange;
end;
function TDdeCliItem.RefreshData: Boolean;
var
ddeRslt: LongInt;
DdeDat: HDDEData;
begin
Result := False;
if (FCliConv.Conv <> 0) and (FHszItem <> 0) then
begin
if FCliConv.WaitStat = True then Exit;
DdeDat := DdeClientTransaction(nil, DWORD(-1), FCliConv.Conv, FHszItem,
FCliConv.DdeFmt, XTYP_REQUEST, 1000, @ddeRslt);
if DdeDat = 0 then Exit
else begin
StoreData(DdeDat);
DdeFreeDataHandle(DdeDat);
Result := True;
Exit;
end;
end;
DataChange;
end;
function TDdeCliItem.AccessData(DdeDat: HDDEData; pDataLen: PDWORD): Pointer;
begin
Result := DdeAccessData(DdeDat, pDataLen);
end;
procedure TDdeCliItem.ReleaseData(DdeDat: HDDEData);
begin
DdeUnaccessData(DdeDat);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -