Autor |
Beitrag |
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: So 18.02.07 13:00
Hi.
Ich will eine Stoppuhr bauen (soweit kein Problem) und diese will ich per message starten und stoppen. So kann ich dann in jeder meiner Anwendungen diese Stoppuhr starten / beenden. Soweit der Plan. Nur gibt es da diverse Probleme:
1) Wie verhindere ich überschneidungen mit den messages von Windows und andren Programmen (wenn ich z.B. "1" schicke, dann ist das sicher eine Windows-message)
2) Wie kann ich diese Message schicken, ohne das Handle der Stoppuhr zu wissen? (will das nur so wie beep oder so in den Source einbauen, als Test von Berechnungszeiten usw.)
3) Wo muss meine "Empfangsprozedur" hin, damit ich diese message auch empfange. Würde gerne eine eigenen Unit machen, doch erreicht die message dort auch meine Prozedur?
Thx, ich hoffe, ihr kennt euch aus und könnt mir helfen
Xion
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: So 18.02.07 13:11
Xion hat folgendes geschrieben: | 1) Wie verhindere ich überschneidungen mit den messages von Windows und andren Programmen (wenn ich z.B. "1" schicke, dann ist das sicher eine Windows-message) |
Dazu gibt es benutzerdefinierte Messages (ab WM_USER aufwärts).
Xion hat folgendes geschrieben: | 2) Wie kann ich diese Message schicken, ohne das Handle der Stoppuhr zu wissen? (will das nur so wie beep oder so in den Source einbauen, als Test von Berechnungszeiten usw.) |
Du kannst das Handle per FindWindow etc. suchen und das dann verwenden. Oder du nimmst ne BoradCast-Message, bei der die Nachricht an alle Fenster gesendet wird (davon würde ich dir allerdings abraten, da es zu Nebenwirkungen kommen kann  )
Xion hat folgendes geschrieben: | 3) Wo muss meine "Empfangsprozedur" hin, damit ich diese message auch empfange. Würde gerne eine eigenen Unit machen, doch erreicht die message dort auch meine Prozedur? |
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| type TForm1 = class(TForm) ... private procedure Start(var msg: TMessage); messsage MyMessageID; end; |
Das dürfte dir genug sagen  . Ansonsten frag einfach nach.
|
|
klezmor
      
Beiträge: 558
delphi 6 personal delphi 2005 personal
|
Verfasst: So 18.02.07 14:04
Siehe hier
Funktioniert bei mir wunderbar und ist ziemlich genau.
_________________ "Beware of bugs in the above code; I have only proved it correct, not tried it." Donald Knuth
|
|
Xion 
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: So 18.02.07 20:06
1)
Heiko hat folgendes geschrieben: |
Dazu gibt es benutzerdefinierte Messages (ab WM_USER aufwärts).
|
thx, dadurch kann es natürlich auch zu Überschneidungen kommen (wie du unter 2. auch sagst). Eigene messages müsste man wohl bei Microsoft registrieren lassen, aber das ist ja Quatsch...
2)
Heiko hat folgendes geschrieben: |
Du kannst das Handle per FindWindow
|
genau das ist mir eigentlich zu aufwendig, will es ja nur so schnell in mein Prog einbauen, zu testzwecken. Ist halt doof, wenn man erst groß Handles suchen muss...naja, kann ich ja in eine extra procedure setzen. Mit BroadCast hab ich aber ja dann eben die Überschneidungen...
3)
Heiko hat folgendes geschrieben: |
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| type TForm1 = class(TForm) ... private procedure Start(var msg: TMessage); messsage MyMessageID; end; |
|
diesen Code kenne ich, würde mich nur eben interessieren, ob dieser auch in irgendeiner Klasse (die nichts mit TForm zu tun hat) funktioniert, so dass man es in eine Unit auslagern könnte, die keine Form besitzt
klezmor hat folgendes geschrieben: |
Funktioniert bei mir wunderbar und ist ziemlich genau. |
thx, der Code ist schonmal sehr interessant (ging mir zwar eigentlich mehr um das Problem mit den messages, aber der Code hilft mir schonmal SEHR weiter  )
Xion
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: So 18.02.07 20:18
Xion hat folgendes geschrieben: | 1)
Heiko hat folgendes geschrieben: |
Dazu gibt es benutzerdefinierte Messages (ab WM_USER aufwärts).
|
thx, dadurch kann es natürlich auch zu Überschneidungen kommen (wie du unter 2. auch sagst). Eigene messages müsste man wohl bei Microsoft registrieren lassen, aber das ist ja Quatsch... |
Neeee, bei MS brauchste die nicht registrieren  . Das musste einfach für deine AP so festlegen.
Xion hat folgendes geschrieben: | 3)
Heiko hat folgendes geschrieben: |
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| type TForm1 = class(TForm) ... private procedure Start(var msg: TMessage); messsage MyMessageID; end; |
|
diesen Code kenne ich, würde mich nur eben interessieren, ob dieser auch in irgendeiner Klasse (die nichts mit TForm zu tun hat) funktioniert, so dass man es in eine Unit auslagern könnte, die keine Form besitzt |
Du brauchst lediglich eine Klasse, die ein Handle hat. Also alle Objekte die von TWinControl abgeleitet sind.
Xion hat folgendes geschrieben: | klezmor hat folgendes geschrieben: |
Funktioniert bei mir wunderbar und ist ziemlich genau. |
thx, der Code ist schonmal sehr interessant (ging mir zwar eigentlich mehr um das Problem mit den messages, aber der Code hilft mir schonmal SEHR weiter )
Xion |
Aber durch die Messages wird es wieder ungenau  . Wenn du mit Messages arbeitet, was du bei deinem Programmziel machen musst, reicht dann eigentlich GetTickCount aus  .
|
|
Xion 
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Mo 19.02.07 10:40
Heiko hat folgendes geschrieben: | Neeee, bei MS brauchste die nicht registrieren . Das musste einfach für deine AP so festlegen.
|
wenn ich aber ne message wöllte, die nur für mein Programm zählt, dann schon, oder? weil ansonsten könnte ich ja, wenn ich nen BroadCast rausschicke mehrere Programme ansprechen. Naja, egal... //Edit: RegisterMessage regelt das, hab ich gesehen... Heiko hat folgendes geschrieben: | Du brauchst lediglich eine Klasse, die ein Handle hat. Also alle Objekte die von TWinControl abgeleitet sind.
|
thx, sowas in der Art wollte ich hören :mrgreen: Heiko hat folgendes geschrieben: | Aber durch die Messages wird es wieder ungenau . Wenn du mit Messages arbeitet, was du bei deinem Programmziel machen musst, reicht dann eigentlich GetTickCount aus . |
so genau muss es ja auch gar nicht sein. Mal sehen, wie ich das dann mache. Thx für eure Hilfe 
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
Zuletzt bearbeitet von Xion am Mo 19.02.07 12:03, insgesamt 1-mal bearbeitet
|
|
Xion 
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Mo 19.02.07 11:17
also, ich hab jetzt eine Klasse (abgeleitet von TWinControl). Jetzt muss ich aber meine Message an das Handle des WinControls schicken, aber wie komm ich den von außerhalb des Programms auf das Handle der Komponente?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| type TMsgTimer=class(TWinControl) private Time: Integer; TimerPic: TAdvImage; TimerLbl: TLabel; procedure StartTimer(var msg: TMessage); message WM_STARTTIMER; procedure StopTimer(var msg: TMessage); message WM_STOPTIMER; end;
...
SendMessage(MsgTimer.Handle,WM_USER+1,0,0); |
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Mo 19.02.07 20:26
Es gibt ne WinAPI dafür, Klassen herauszusuchen, die einen bestimmten Namen haben (FindWindow der erste Paramater glaub ich [hab gerade kein Delphi offen]). Und wenn du einen schönen Namen hast, den kein anderes Programm verwendet, haste gleich dein entsprechendes Handle.
|
|
Xion 
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Di 20.02.07 12:30
Thx,
aber irgendwie gehts nicht so ganz  ...
Delphi-Quelltext 1:
| SendMessage(FindWindow('MsgTimer','Nynx'),WM_USER+1,0,0); |
bzw.
Delphi-Quelltext 1:
| SendMessage(FindWindow('TMsgTimer','MsgTimer'),WM_USER+1,0,0); |
die procedure StartTimer wird aber nicht aufgerufen. Darf ich eigentlich die proceduren als private setzen? Weil die MainForm hat ja dann keinen Zugriff drauf.
Xion
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Di 20.02.07 19:17
Bei den beiden Kombinationen geht es garantiert nicht  , denn:
Zitat: | The FindWindow function retrieves a handle to the top-level window whose class name and window name match the specified strings. This function does not search child windows. |
Also würde deine 2. variante schon einmal nicht funktionieren.
Und die erste dürfte nicht funktionieren, da deine Klasse vermtulich T anfängt. Und der 2. Paramater muss der Titel der App sein (also was Application.Title beinhaltet).
|
|
Xion 
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Mi 21.02.07 11:04
Thx
Heiko hat folgendes geschrieben: |
Und die erste dürfte nicht funktionieren, da deine Klasse vermtulich T anfängt. Und der 2. Paramater muss der Titel der App sein (also was Application.Title beinhaltet). |
hab ich gemacht, geht aber immernoch nicht...also, mal ganz genau:
Ich hab ne Application mit ner Form. Eine zusätliche Unit (UClock) beinhaltet die Klasse TMsgTimer. Diese Klasse ist von TWinControl abgeleitet und beinhaltet die Empfangs-proceduren:
aus UClock 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| unit UClock;
interface
uses ...
const WM_STARTTIMER=WM_USER+1; const WM_STOPTIMER=WM_USER+2;
implementation
uses Nynx2;
type TMsgTimer=class(TWinControl) public procedure StartTimer(var msg: TMessage); message WM_STARTTIMER; procedure StopTimer(var msg: TMessage); message WM_STOPTIMER; private ... end;
... |
Die Klasse wird auf der Form "erschaffen" und hat auch als Parent die Form.
[Delphi=" "Erschaffung" von TMsgTimer"]
...
MsgTimer:=TMsgTimer.Create(MainForm);
MsgTimer.Parent:=MainForm;
...
[/Delphi]
und so sind die proceduren deklariert:
Empfangsproceduren 1: 2: 3: 4: 5: 6: 7: 8: 9:
| procedure TMsgTimer.StartTimer(var msg: TMessage); begin ... end;
procedure TMsgTimer.StopTimer; begin ... end; |
Dann hab ich versucht unter TMainForm.OnMouseDown eine message zu schicken:
TMainForm.OnMouseDown 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure TMainForm.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var ... H: THandle; begin ... SendMessage(H,WM_USER+1,0,0); end; |
kann es daran liegen, dass es nicht geht, weil MsgTimer auf TMainForm erschaffen wird?
Thx, dass ihr euch so bemüht 
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Mi 21.02.07 17:30
Ich sag nur noch eins: MSDN IST DEIN FREUND!
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs;
type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormClick(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private public end;
type TMyClass = class(TWinControl) private
public procedure MyMsg(var Msg: TMessage); message WM_USer+1; end;
var Form1: TForm1; test: TMyClass;
implementation
{$R *.dfm}
procedure TForm1.FormClick(Sender: TObject); var h: HWND; begin h:=FindWindow('TForm1', nil); h:=FindWindowEx(h, 0, 'TMyClass', ''); Form1.Caption:=IntToStr(h)+' '+IntToStr(test.Handle); SendMessage(h, WM_User+1, 0, 0); end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin test.Free; end;
procedure TForm1.FormCreate(Sender: TObject); begin test:=TMyClass.Create(Self); test.Parent:=Form1; end;
procedure TMyClass.MyMsg(var Msg: TMessage); begin ShowMessage('sd'); end;
end. |
|
|
Xion 
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Do 22.02.07 10:59
aah, danke  funtkioniert.
nur ein Problem habe ich noch: Ich krieg die message nicht in die Unit rein. Hab jetzt den Empfang auf die Form gepackt, und die ruft dann die MsgTimer-procedure auf.
Aber ansonsten funktionierts.
Danke 
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
|