關于mailslot的問題. (100分)

  • 主题发起人 主题发起人 bini
  • 开始时间 开始时间
B

bini

Unregistered / Unconfirmed
GUEST, unregistred user!
我需要此函數向局域網內的win98和win200/nt4.0各工作站定時發送消息.由于時間關系.
就麻各位弄一份源程序.感激不盡.(注:各工作站無專門的客戶端,讓win98收到自動彈出
winpopup....)
 
98可以吗?在没有Winpopup运行的情况下,能收到别人(就算是Winpopup)发来的
消息吗??我记得在NT上可以,那是因为NT的服务,98可以吗?没有客户端,没有
运行WINPOPUP,可以吗?
 
我有个控件带源代码的,不复杂而且好用

就是它,不过不能在D6,5,4里直接用,个别api参数要改一下,我在3和4里用过,5,6没试如何修改

unit Messenger;

interface

{$LONGSTRINGS ON} // Equal {$H+}

uses
ExtCtrls, Windows, SysUtils, Classes,Dialogs;

type
TMainMessenger = Class;
TSignalThread = class(TThread)
private
FMailSlot : TMainMessenger;
protected
procedure Execute; override;
Public
Constructor Create(MailSlot : TMainMessenger);
end;
TTimerThread = class(TThread)
private
FMailSlot : TMainMessenger;
protected
procedure Execute; override;
Public
Constructor Create(MailSlot : TMainMessenger);
end;



TNELineArrival = Procedure (Sender : TObject;Origin,Time,Line : string) of Object;
TNEMemoArrival = Procedure (Sender : TObject;Origin,Time : string;MsgLines : TStrings) of Object;
TNEUserListChange = Procedure (Sender : TObject; UserList : TStrings) of Object;
TNEError = Procedure (Sender : TObject;ErrorMsg : string) of object;
TNETimer = Procedure (Sender : TObject) of object;

TMainMessenger = class(TComponent)
private
FWaitThread : TSignalThread;
FTimerThread : TTimerThread;
LocalHandle,RemoteHandle : THandle;
ActiveFlag : Boolean;
FComputer,FUser : string;
Server,FBoxName,LocalPath,RemotePath : string;
MaxMsgSize,MsgCount,NextMsgSize,MsgSize : DWORD;
MsgType,MsgTime,MsgSender,MsgText : string;
OutStrings,InStrings,UserList,MemoLines : TStringList;
NewLine : String;
FInterval : word;
FTimerActive : boolean;
FLineArrival : TNELineArrival;
FMemoArrival : TNEMemoArrival;
FUserListChange : TNEUserListChange;
FError : TNEError;
FTimer : TNETimer;
Procedure SendOutStrings(Recipient : string);
Procedure SendCommand(Recipient,Command : string);
Procedure AddUser(Name : string);
Procedure DeleteUser(Name : string);
protected
Procedure DoLineArrival(Const FMSender,FMTime,FMText : string); virtual;
Procedure DoMemoArrival(const FMSender,FMTime : string;MLines : Tstrings); virtual;
Procedure DoUserListChange(Const CompList : TStringList); virtual;
Procedure DoErrorReport(const Error : string); virtual;
public
Constructor Create(AOwner : TComponent); Override;
Destructor Destroy; override;
Procedure Activate;
Procedure DeActivate;
Procedure SetName(const NewName : TComponentName); override;
Procedure SetBoxName(NewName : string);
Procedure SetInterval(time : word);
Procedure ReadMessage;
Procedure ProcessCommand;
Procedure SendLine(Recipient,Text : string);
Procedure SendMemo(Recipient : string;Lines : TStrings);
Procedure Broadcast(text : string);
procedure DoTimer;
Property OnNewLine : TNELineArrival read FLineArrival write FLineArrival;
Property OnNewMemo : TNEMemoArrival read FMemoArrival write FMemoArrival;
Property OnUserListChange : TNEUserListChange Read FUserListChange Write FUserListChange;
Property OnError : TNEError read FError write FError;
Property OnTimer : TNETimer read FTimer write FTimer;
published
end;

TMessenger = class(TMainMessenger)
Published
Property Computer : string read FComputer;
Property User : string read FUser;
Property BoxName : string read FBoxName write SetBoxName;
Property Interval : word read FInterval write SetInterval;
Property OnNewLine;
Property OnNewMemo;
Property OnUserListChange;
Property OnError;
Property OnTimer;
end;

procedure Register;

implementation

//---------- Component Registration ------------------------------------------

procedure Register;
begin
RegisterComponents('3rdParty', [TMessenger]);
end;



//---------- Thread Procedures -----------------------------------------------

Constructor TSignalThread.Create(MailSlot : TMainMessenger);
Begin
Inherited Create(False);
Priority := tpNormal;
FMailSlot := MailSlot;
end;

Procedure TSignalThread.Execute;
Begin
While Not Terminated do
Begin
GetMailSlotInfo(FMailSlot.LocalHandle,NIL, FMailSlot.NextMsgSize,
@FMailSlot.MsgCount, NIL);
If FMailSLot.MsgCount > 0 Then
Synchronize(FMailSLot.ReadMessage);
Sleep(1);
end;
end;


Constructor TTimerThread.Create(MailSlot : TMainMessenger);
Begin
Inherited Create(False);
Priority := tpNormal;
FMailSlot := MailSlot;
end;

Procedure TTimerThread.Execute;
Begin
While Not Terminated do begin
Synchronize(FMailSLot.DoTimer);
Sleep(FMailslot.FInterval);
end;
end;


Procedure TMainMessenger.DoTimer;
begin
if assigned(FTimer) then FTimer(Self);
end;


//----------- Signaler StartUp/ShutDown -----------------------------------------

Constructor TMainMessenger.Create(AOwner : TComponent);
var
temp : array[0..255] of char;
len : integer;
Begin
Inherited Create(AOwner);
FBoxName := 'SignalBox';
FInterval := 1000;
FWaitThread := NIL;
FTimerThread := NIL;
len := 255;
GetComputerName(temp,len);
FComputer := StrPas(temp);
len := 255;
GetUserName(temp,len);
FUser := StrPas(temp);
OutStrings := TStringList.Create;
InStrings := TStringList.Create;
UserList := TStringList.Create;
MemoLines := TStringList.Create;
end;

Destructor TMainMessenger.Destroy;
begin
if ActiveFlag = true then DeActivate;
UserList.Free;
OutStrings.Free;
InStrings.Free;
MemoLines.Free;
inherited Destroy;
end;

Procedure TMainMessenger.Activate;
var
i,j : integer;
begin
If ActiveFlag = true then begin
DoErrorReport('You tried to Activate an active TMessenger component');
exit;
end;
FWaitThread := TSignalThread.Create(Self);
if FWaitThread = nil then begin
DoErrorReport('Could not Start TMessenger Timer Thread');
exit;
end;
FTimerThread := TTimerThread.Create(Self);
Server := '.';
LocalPath := '//' + Server + '/mailslot/' + FBoxName;
LocalHandle := CreateMailSlot(PChar(LocalPath),MaxMsgSize,0,nil);
if LocalHandle = INVALID_HANDLE_VALUE then begin
FWaitThread.Terminate;
FWaitThread := nil;
FTimerThread.Terminate;
FTimerThread := nil;
DoErrorReport('Could not Create Mail Slot');
exit;
end;
SendCommand('*','ONLINE_NOTIFY');
ActiveFlag := true;
end;


Procedure TMainMessenger.DeActivate;
begin
if ActiveFlag = false then begin
DoErrorReport('Cannot Deactivate an Inactive TMessenger Component');
exit;
end;
if FWaitThread <> nil then begin
FWaitThread.Terminate;
FWaitThread := nil;
end;
if FTimerThread <> nil then begin
FTimerThread.Terminate;
FTimerThread := nil;
end;
CloseHandle(LocalHandle);
SendCommand('*','OFFLINE_NOTIFY');
ActiveFlag := False;
end;


//-------------- Set Property Procedures --------------------------------------

Procedure TMainMessenger.SetName(const NewName: TComponentName);
Begin
Inherited SetName(NewName);
end;

Procedure TMainMessenger.SetBoxName(NewName : string);
begin
if FBoxName <> NewName then begin
FBoxName := NewName;
if ActiveFlag = true then begin
DeActivate;
Activate;
end;
end;
end;

Procedure TMainMessenger.SetInterval(Time : word);
begin
if FInterval <> Time then FInterval := Time;
end;


//------------- Message Retrieval Procedures ----------------------------------

Procedure TMainMessenger.ReadMessage;
var
i : integer;
begin
Instrings.Clear;
SetLength(NewLine,NextMsgSize);
ReadFile(LocalHandle,PChar(NewLine)^,NextMsgSize,MsgSize,nil);
Instrings.Text := NewLine;
FWaitThread.Suspend;
if Instrings.Count > 3 then begin
MsgType := Instrings[0];
MsgTime := Instrings[1];
MsgSender := Instrings[2];
MsgText := Instrings[3];
end;
if Instrings.Count > 5 then begin
MemoLines.Clear;
for i := 4 to Instrings.Count - 2 do begin
MemoLines.Add(Instrings);
end;
end;
if MsgType = 'COMMAND_MSG' then ProcessCommand;
if MsgType = 'LINE_MSG' then DoLineArrival(MsgSender,MsgTime,MsgText);
if MsgType = 'MEMO_MSG' then DoMemoArrival(MsgSender,MsgTime,MemoLines);
Instrings.Clear;
FWaitThread.Resume;
end;

Procedure TMainMessenger.ProcessCommand;
begin
if MsgSender = FComputer then exit;
if MsgText = 'ONLINE_NOTIFY' then begin
AddUser(MsgSender);
SendCommand(MsgSender,'ONLINE_RESPONSE');
end;
if MsgText = 'ONLINE_RESPONSE' then AddUser(MsgSender);
if MsgText = 'OFFLINE_NOTIFY' then DeleteUser(MsgSender);
end;

Procedure TMainMessenger.AddUser(Name : string);
var
i : Integer;
j : boolean;
begin
j := false;
if UserList.Count > 0 then begin
for i := 0 to UserList.Count - 1 do begin
if UserList = Name then j := true;
end;
end;
if j = true then exit;
UserList.Add(Name);
DoUserListChange(UserList);
end;

Procedure TMainMessenger.DeleteUser(Name : string);
var
i,Num : Integer;
j : boolean;
begin
j := false;
Num := 0;
if UserList.Count > 0 then begin
for i := 0 to UserList.Count - 1 do begin
if UserList = Name then begin
j := true;
Num := i;
end;
end;
end;
if j = false then exit;
UserList.Delete(Num);
DoUserListChange(UserList);
end;

//------------- Message Sending Procedures ------------------------------------

Procedure TMainMessenger.SendOutStrings(Recipient : string);
var
len : DWORD;
begin
if OutStrings.Count > 0 then begin
RemotePath := '//' + Recipient + '/mailslot/' + FBoxName;
RemoteHandle := CreateFile(PChar(RemotePath),GENERIC_WRITE,FILE_SHARE_READ,
nil,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,-1);
if RemoteHandle = INVALID_HANDLE_VALUE then begin
DoErrorReport('Could not Open a Remote Mail Slot');
exit;
end;
WriteFile(RemoteHandle,Pointer(Outstrings.text)^,Length(OutStrings.text),len,nil);
OutStrings.Clear;
end;
end;

Procedure TMainMessenger.SendLine(Recipient,Text : string);
begin
if Recipient = '*' then exit;
Outstrings.Add('LINE_MSG');
Outstrings.Add(TimeToStr(Time));
OutStrings.Add(FComputer);
OutStrings.Add(text);
OutStrings.Add('END_MESSAGE');
SendOutStrings(Recipient);
end;

Procedure TMainMessenger.Broadcast(text : string);
begin
Outstrings.Add('LINE_MSG');
Outstrings.Add(TimeToStr(Time));
OutStrings.Add(FComputer);
OutStrings.Add(text);
OutStrings.Add('END_MESSAGE');
SendOutStrings('*');
end;

Procedure TMainMessenger.SendMemo(Recipient : string;Lines : TStrings);
var
i : integer;
begin
if Recipient = '*' then exit;
Outstrings.Add('MEMO_MSG');
Outstrings.Add(TimeToStr(Time));
OutStrings.Add(FComputer);
OutStrings.Add('BEGIN_MEMO');
if Lines.Count > 0 then begin
for i := 0 to Lines.Count -1 do begin
OutStrings.Add(Lines);
end;
end;
OutStrings.Add('END_MESSAGE');
SendOutStrings(Recipient);
end;

Procedure TMainMessenger.SendCommand(Recipient,Command : string);
begin
Outstrings.Add('COMMAND_MSG');
Outstrings.Add(TimeToStr(Time));
OutStrings.Add(FComputer);
OutStrings.Add(Command);
OutStrings.Add('END_MESSAGE');
SendOutStrings(Recipient);
end;

//----------- Event Handler Procedures ---------------------------------------

Procedure TMainMessenger.DoLineArrival(const FMSender,FMTime,FMText : string);
begin
if Assigned(FLineArrival) then FLineArrival(Self,MsgSender,MsgTime,MsgText);
end;

Procedure TMainMessenger.DoMemoArrival(const FMSender,FMTime : string;MLines : Tstrings);
begin
if Assigned(FMemoArrival) then FMemoArrival(Self,MsgSender,MsgTime,MemoLines);
end;

Procedure TMainMessenger.DoUserListChange(Const CompList : TStringList);
begin
If Assigned(FUserListChange) Then FUserListChange(Self,CompList);
end;

Procedure TMainMessenger.DoErrorReport(const Error : string);
begin
If Assigned(FError) Then FError(Self,Error);
end;

end.
 
to:wdl
請發至我的信箱:biniyi@1010.com
thanks.
 
已经发送,查收
 
收到,getcomputername等函數...在D6中要修改了.integer型的那種得改為Dword指針型.
等等....單位統一用D6了.
 
被國外一32歲程序員解決謝謝各位.有時間共同分享.
 
多人接受答案了。
 
后退
顶部