Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Probleme mit Aufruf von procedure


DiamondDog - Do 28.08.08 10:14
Titel: Probleme mit Aufruf von procedure
Hallo Leute,
ich hab das Problem das ich gerne diese procedure, von anderer Stelle aus aufrufen möchte:

Delphi-Quelltext
1:
procedure TQipPlugin.DrawSpecContact(PlugMsg: TPluginMessage);                    

Ich hab das schon zb so versucht:

Delphi-Quelltext
1:
2:
3:
4:
procedure TfrmMain.MultilineButton1Click(Sender: TObject);
begin
plug.DrawSpecContact();
end;
Leider funktioniert das nicht, ich bekomme immer die Fehlermeldung:
"Nicht genügen wirkliche Parameter"

Kann mir jemand sagen, wie ich es schaffe die procedure aufzurufen?

Dnake schon mal

Mfg Dog


Moderiert von user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Do 28.08.2008 um 10:19


Mike19 - Do 28.08.08 10:20

Die Antwort gibt doch schon der Compiler, muss da nicht irgendetwas in der Klammer stehen?


iKilledKenny - Do 28.08.08 10:21

Naja, die procedure erwartet den Parameter (PlugMsg: TPluginMessage), also musst du den auch übergeben.


Delphi-Quelltext
1:
2:
3:
var msg : TPluginMessage;
...
plug.DrawSpecContact(msg);


DiamondDog - Do 28.08.08 11:42

@ iKilledKenny wenn ich das so mache schmiertdas ganze Programm ab weil er warscheinlich zu dem Zeitpunkt dann nix mit msg : TPluginMessage anfangen kann.

Mal zur erklärung was ich eigendlich vorhabe.
Also ich hab die nachfolgende Procedure und wollte da einach nur das der Text alle paar sec aktualisiert wird.
Auf meiner Form geht das wunderbar würde es halt nur gerne so haben das beide Texte zu gleich auktualiesiert werden.


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:
63:
procedure TQipPlugin.DrawSpecContact(PlugMsg: TPluginMessage);
var ContactId : DWord;
    //Data      : Pointer;
    Cnv       : TCanvas;
    R         : PRect;
    wStr      : WideString;
    R1        : TRect;
    TestIcon  : HICON;
//   TestIcon  : TICON;
begin
  if not Assigned(FfrmMain) then Exit;
  //get unique contact id from msg
  ContactId := PlugMsg.WParam;

  //actually all incoming ContactIDs will be only of your plugin, but here i made condition just for example
  if (ContactId <> FfrmMain.UniqContactId) then Exit;

  //get your Data pointer which you added when sent PM_PLUGIN_SPEC_ADD_CNT.
  //IMPORTANT!!! Do NOT make here any heavy loading actions, like cycles FOR, WHILE etc.
  //That's why you have to add Data pointer to PM_PLUGIN_SPEC_ADD_CNT, to get quick access to your data.
  //Data not used here in this example because plugin added only one contact
  //Data      := Pointer(PlugMsg.LParam);

  //create temporary canvas to draw the contact
  Cnv       := TCanvas.Create;
  try

  //get canvas handle from msg
  Cnv.Handle := PlugMsg.NParam;

  //get drawing rectangle pointer from msg
  R := PRect(PlugMsg.Result);

  //this needed to draw text over contact list backgroud
  SetBkMode(Cnv.Handle, TRANSPARENT);

  //get test icon to draw
  TestIcon := LoadImage(0, IDI_INFORMATION, IMAGE_ICON, 1616, LR_DEFAULTCOLOR or LR_SHARED or LR_LOADTRANSPARENT);
  //draw icon
  DrawIconEx(Cnv.Handle, 82, TestIcon, 161600, DI_NORMAL);
  //dont forget to destroy your icon
  DestroyIcon(TestIcon);

  //text of your contact
  wStr := FfrmMain.user + ' ' + FfrmMain.Edit2.Text;

  //Use Tahoma to draw your text, because its unicode font
  Cnv.Font.Name  := 'Tahoma';
  Cnv.Font.Color := clNavy;
  Cnv.Font.Size  := 8;
  Cnv.Font.Style := [fsBold];

  R1 := Rect(R^.Left + 26 + FSpecLeft, R^.Top + 1 + FSpecTop, R^.Right, R^.Bottom);

  //text drawing
  //IMPORTANT! If your text may have non ascii symbols, then use unicode drawing.
  DrawTextW(Cnv.Handle, PWideChar(wStr), Length(wStr), R1, DT_LEFT);

  finally
  //free canvas
  Cnv.Free;
  end;
end;


So siehts auf der Form aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
procedure TfrmMain.MultilineButton1Click(Sender: TObject);
begin
Timer2.Enabled:=True;
Timer3.Enabled:=True;
//---------------------
text:=GetHTML(Edit1.Text);

user:=copy(text,22,1000);

datuhr:=copy(text,1,20);
datum:=copy(datuhr,1,11);
uhr:=copy(datuhr,12,20);

Label1.Caption:=user + ' ' + Edit2.Text;
Label4.Caption:='Datum: '+ datum;
Label5.Caption:='Uhrzeit: ' + uhr + ' Uhr' ;
//----------------------
if Label1.Caption='' then Label1.Caption:='0' + Edit2.Text;
Label2.Caption:='*';
end;
und wenn halt der Button geklickt wird soll auch der Text von DrawSpecContact aktualisiert werden.


uko - Do 28.08.08 11:52

Du hast msg schon mit den benötigten Daten gefüllt, oder?

Grüße,
Uli


iKilledKenny - Do 28.08.08 11:52

Das war PseudoCode und sollte nur veranschaulichen, dass du ein Object von diesem Typ übergeben musst. Wo auch immer das herkommt...


DiamondDog - Do 28.08.08 15:07

Wie mach ich das zb richtig vll gehts ja damit:

Delphi-Quelltext
1:
2:
3:
[...]
if FfrmMain.MultilineButton1.Cklick=True then
[...]
Ich weiß das ist falsch wuste nicht genau wie es richtig geht.
Kann mir jemand sagen wie das funktioniert bzw richtig wäre?


uko - Do 28.08.08 15:28

Das kann ich Dir auch nicht sagen. Kenn ja deine Pluginengine nicht. :-) Aber irgendwas von der Güte:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
procedure TfrmMain.MultilineButton1Click(Sender: TObject);
var
  msg: TPluginMessage;
begin
  // bisheriger Code aus Form
...

  // Msg-Daten fuellen: welche Properties, mußt Du selbst nachschauen
  msg := TPluginMessage.Create;  // falls eine Klasse, bei reinem Record-Typ nicht
  msg.property1 := ...;
  msg.property2 := ...;

  // und and Plugin senden
  plug.DrawSpecContact(Msg);
end;


Grüße,
Uli


DiamondDog - Fr 29.08.08 09:46

Mir ist gerade aufgefallen das ich was vergessen habe zu Posten, hiermit wird der Kontackt erstellt wenn die Chekbox True ist und wenn fals wird er gelöscht.
Vieleicht ist das ja noch Hilfreich:

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:
procedure TfrmMain.ckAddContactClick(Sender: TObject);
begin
   if not ckAddContact.Checked then
   begin
      if (UniqContactId = 0then Exit;
      PlugMsg1.Msg    := PM_PLUGIN_SPEC_DEL_CNT;
      PlugMsg1.WParam := UniqContactId;
      PlugMsg1.DllHandle := FDllHandle;
      FPluginSvc.OnPluginMessage(PlugMsg1);
      UniqContactId := 0;
   end
   else
   if (UniqContactId=0then
   begin
      PlugMsg1.Msg    := PM_PLUGIN_SPEC_ADD_CNT;
      PlugMsg1.WParam := 19;
      PlugMsg1.LParam := 0;
      PlugMsg1.DllHandle := FDllHandle;
      FPluginSvc.OnPluginMessage(PlugMsg1);

      if (PlugMsg1.Result <> 0then UniqContactId := PlugMsg1.Result;
   end;
end;

Ps: Hab das ganze mal zur Not angehängt.


Yogu - Fr 29.08.08 11:34

Wenn du OnPluginMessage nun wieder aufrufen möchtest, als ob auf ckAddContact geklickt wurde, dann musst du eben genau diesen Quelltext wieder ausführen. Am besten packst du den gesamten Code der TfrmMain.ckAddContactClick in eine Prozedur, die du dann zum einen beim Klick auf die CheckBox aufrufst, und zum anderen im Timer.


DiamondDog - Sa 30.08.08 10:15

Das ganz in eine Procedure hab ich jetzt versucht das geht leider so nicht.
Schätze das hängt mit ContactId zusammen.
Hab das auch mal als Buttonklick versucht:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
   if (UniqContactId=0then
   begin
      PlugMsg1.Msg    := PM_PLUGIN_SPEC_ADD_CNT;
      PlugMsg1.WParam := 19;
      PlugMsg1.LParam := 0;
      PlugMsg1.DllHandle := FDllHandle;
      FPluginSvc.OnPluginMessage(PlugMsg1);

      if (PlugMsg1.Result <> 0then UniqContactId := PlugMsg1.Result;
   end;
so gehts es nicht, nehme ich aber das raus:

Delphi-Quelltext
1:
   if (UniqContactId=0then                    
dann wird ein neuer Conackt erstellt was aber nicht Sin der Sache ist.
Ich müste irgend wie gucken das er beim Klick auf den Button die selbe ContactId bekommt, die er ja schon hat. Weil sonst wird der Kontackt immer weiter nach unten versetzt, er soll aber da bleiben wo er erstellt wurde.

Edit:
Hab mal einwenig rumprobiert und wenn ich das bei Buttonklick so habe:

Delphi-Quelltext
1:
2:
3:
4:
   begin
      FPluginSvc.OnPluginMessage(PlugMsg1);
      UniqContactId := UniqContactId;
   end;
dann wird auch aktualisiert. Problem dabei ist es wird immer ein neuer Acount erstellt der leer ist. Hab dann nach zB. 5 Buttonklicks 5 leere Kontackte in der Liste. Also müste ich eigendlich nur wissen wie ich die bei klick sofort wieder löschen kann oder wie sie garnicht erst entstehen.


uko - Sa 30.08.08 11:25

Was ist jetzt eigentlich überhaupt dein Problem? Mit deinem ursprünglichen Post hat dein letzter ja irgendwie nicht mehr so viel gemeinsam, oder? Schreib doch einfach nochmal genau, was das Problem ist!

Grüße,
Uli


DiamondDog - Sa 30.08.08 11:37

user profile iconuko hat folgendes geschrieben:
Mit deinem ursprünglichen Post hat dein letzter ja irgendwie nicht mehr so viel gemeinsam, oder?


Doch ist immer noch das Selbe Problem.
Also versuch ich das nochmal zu erklären.
Also ich erstelle mit der Checkbox einen Kontackt in meiner Liste oder Lösche ihn.
True = Erstellen
False = Löschen
Jetzt zu dem was ich machen will, ich möchte halt den Text des Kontacktes aktualiesieren weil dieser sich ständig ändert.
Problem dabei ist das aufrufen zum Aktualiesieren da weiß ich nciht wie ich das machen soll.
Da der Kontackt seine speziele Id bekommt beim erstellen muß ich den Kontackt ja wieder mit sein Id ansprechen, weil er sonst neu an anderer Stelle erstellt werden würde.

Hoffe das das als Erklärung verständlich genug ist.
Weil besser kann ich es irgendwie nicht erklären.


uko - Sa 30.08.08 11:57

Du willst also im Endeffekt für einen bestehenden Kontakt die Methode DrawSpecContact aufrufen? Dann mußt Du soweit ich das verstehe nur die Message PM_PLUGIN_SPEC_DRAW_CNT an die Pluginengine schicken. Ich vermute, daß Du bisher immer PM_PLUGIN_SPEC_ADD_CNT schickst zum aktualisieren, dann wird natürlich auch immer ein neue Kontakt angelegt, da das PLugin ja UniqContactId nach dem erzeugen setzt.
Versuch mal, die Unit u_qip_plugin.pas zu verstehen, dann siehst Du wahrscheinlich klarer. :)

Grüße,
Uli


DiamondDog - Sa 30.08.08 13:10

Ich hab mir jetzt mal die u_plugin_info angesehn und das hier gefunden:

Delphi-Quelltext
1:
PM_PLUGIN_SPEC_REDRAW     = 50//plugin -> qip, plugin can redraw own special contact when needed. WParam is unique dword id of contact.                    
wenn ich das richtig verstehe ist das doch zum aktualisieren des Kontacktes oder?
Nur was ich nicht weiß ist wie die Procedure dafür aussehn muß um zu aktualisieren.


uko - Sa 30.08.08 14:36

Ich würd's so probieren:

Delphi-Quelltext
1:
2:
3:
4:
5:
// PM_PLUGIN_SPEC_REDRAW     = 50; //plugin -> qip, plugin can redraw own special contact when needed. WParam is unique dword id of contact.
PlugMsg1.Msg    := PM_PLUGIN_SPEC_REDRAW; 
PlugMsg1.WParam := UniqContactId; // Hier die ID des Contacts rein, den Du neu zeichnen willst
PlugMsg1.DllHandle := FDllHandle; 
FPluginSvc.OnPluginMessage(PlugMsg1);


Grüße,
Uli


DiamondDog - So 31.08.08 18:51

Ne hab es os versucht das geht leider nicht hab auch n bischen rumprobiert aber leider ohne Erfolg. Wäre echt super wenn mir da jemand weiter Helfen kann.


Hidden - So 31.08.08 19:03

Hi,

user profile iconDiamondDog hat folgendes geschrieben:

Delphi-Quelltext
1:
if FfrmMain.MultilineButton1.Cklick=True then                    

Warum du nicht auf true oder false vergleichen solltest [http://www.delphi-forum.de/viewtopic.php?t=83487&highlight=vergleich+true] ;)

mfG,


uko - Mo 01.09.08 06:29

Guten Morgen,

user profile iconDiamondDog hat folgendes geschrieben:
Ne hab es os versucht das geht leider nicht hab auch n bischen rumprobiert aber leider ohne Erfolg. Wäre echt super wenn mir da jemand weiter Helfen kann.


Ja und was geht dann nicht? Wie soll Dir jemand helfen, wenn Du nicht genau sagst, was nicht funktioniert. :roll:
Hast Du denn schon mit dem Debugger verfolgt, wie weit Du dann kommst, sprich: wird DrawSpecContact denn überhaupt aufgerufen, wenn Du die Message an das Plugin schickst?

Grüße,
Uli


DiamondDog - Di 02.09.08 17:44

Ne mit dem Debugger hab ich das nicht gemacht weil ich nicht weiß, wie ich das damit ans laufen bekomme.
Das was ich schreibe ja eine dll die als Plugin in den Ordner muss:
C:\Programme\QIP Infium\Plugins
und dann muß ich ja noch die Exe hier aufrufen damit das Plugin im Hauptprogramm geladen wird:
C:\Programme\QIP Infium\infium.exe

Wenn mir jemand sagt wie das geht dann mach ich das...


DiamondDog - Mi 03.09.08 17:13

Weiß den niemand wie ich das im Debugger zum laufen bekomme?


uko - Mi 03.09.08 17:25

Schau mal hier nach (z.B.): http://www.delphipraxis.net/topic120565_d7+und+debug+in+dll.html&highlight=dll+debuggen

Kurzfassung: bei Startparametern Hostanwendung setzen (C:\Programme\QIP Infium\infium.exe)

Grüße,
Uli


DiamondDog - Do 04.09.08 19:38

Hab rausgefunden wie es geht:

Delphi-Quelltext
1:
2:
3:
4:
PlugMsg1.Msg    := PM_PLUGIN_SPEC_REDRAW;
PlugMsg1.WParam := UniqContactId;
PlugMsg1.DllHandle := FDllHandle;
FPluginSvc.OnPluginMessage(PlugMsg1);
Trozdem Danke fürs Helfen an alle.