Autor Beitrag
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: So 18.02.07 13:11 
user profile iconXion 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).

user profile iconXion 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 :mrgreen: )

user profile iconXion 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?

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 558


delphi 6 personal delphi 2005 personal
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: So 18.02.07 20:06 
1)
user profile iconHeiko 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)
user profile iconHeiko 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)
user profile iconHeiko hat folgendes geschrieben:

ausblenden 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


user profile iconklezmor 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 :D )

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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: So 18.02.07 20:18 
user profile iconXion hat folgendes geschrieben:
1)
user profile iconHeiko 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.

user profile iconXion hat folgendes geschrieben:
3)
user profile iconHeiko hat folgendes geschrieben:

ausblenden 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.


user profile iconXion hat folgendes geschrieben:
user profile iconklezmor 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 :D )

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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: Mo 19.02.07 10:40 
user profile iconHeiko 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...

user profile iconHeiko 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:


user profile iconHeiko 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 :zustimm:

_________________
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: 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?

ausblenden 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); //hier hätte ich gerne Application.Handle, dann gehts aber nichtmehr :(

_________________
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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: Di 20.02.07 12:30 
Thx,

aber irgendwie gehts nicht so ganz :eyes: ...

ausblenden Delphi-Quelltext
1:
 SendMessage(FindWindow('MsgTimer','Nynx'),WM_USER+1,0,0); //"msgTimer"= Klasse mit den proceduren ; "Nynx"=Name der Application					


bzw.


ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: Mi 21.02.07 11:04 
Thx

user profile iconHeiko 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:

ausblenden 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; {MainUnit}


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:
ausblenden 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:
ausblenden 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
...
   // H:=FindWindowEx(Application.Handle,0,'TMsgTimer',nil); 
   // H:=FindWindowEx(Application.Handle,0,'MsgTimer',nil); 
   // H:=FindWindow('TMsgTimer',PChar(MainForm.Caption));
   // H:=FindWindow('TMsgTimer',PChar(Application.Title));  //geht alles nicht
   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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3169
Erhaltene Danke: 11



BeitragVerfasst: Mi 21.02.07 17:30 
Ich sag nur noch eins: MSDN IST DEIN FREUND!

ausblenden volle Höhe Delphi-Quelltext
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
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  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+100);
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: Do 22.02.07 10:59 
aah, danke :D 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 :zustimm:

_________________
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)