Similar function in Lazarus as ShowMessage, but with delay not "OK" button. lazarus / 32-Linux ---------------------------------------------------------------------- jinx · 2010-11-26 14:55 Hello, I'm building a small app in lazarus in which I need a function/procedure similar to ShowMessage, but instead of give me "OK", it will exit itself in a certain amount of time (some delay variable). Also, is there a function/procedure similar to what kdialog dose: Code: [Select]kdialog --passivepopup "Test ..." P.S. Im building this for KDE, if it helps... ---------------------------------------------------------------------- Leledumbo · 2010-11-26 16:10 QuoteI need a function/procedure similar to ShowMessage, but instead of give me "OK", it will exit itself in a certain amount of time (some delay variable).There's none ATM. You need to create a form with TTimer and show it as modal form. ---------------------------------------------------------------------- jinx · 2010-11-26 16:32 Ok, how?! A form I can create, add a timer to it also, but the rest not really! ---------------------------------------------------------------------- typo · 2010-11-26 16:46 You could not use a Timer or ShowModal, simply set you FormStyle to fsSystemStayOnTop and call it like this: Code: [Select]  FormMessage.Show;   Application.ProcessMessages;   Sleep(1000);   FormMessage.Hide; ---------------------------------------------------------------------- jinx · 2010-11-26 17:02 I need something that modifies, I mean the message in it. Like calling a function: ShowMessage('I need help! ', 1000); 1000 would be the time out, lets say. ---------------------------------------------------------------------- eny · 2010-11-26 17:19 Just create a tiny wrapper function for it. You can make it as simple or complicated as you want. E.g. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure MyShowMessage(Const Fmt : String; const Args : Array of const);begin  ShowMessage(format(Fmt,Args))end; //... MyShowMessage('What''s up number %d', [1000]); ---------------------------------------------------------------------- typo · 2010-11-26 17:28 No, he needs something like this: Code: [Select]procedure ShowTheMessage(ATitle, AMessage :string; ADelay :integer); begin   with formMessage do   begin     Caption := ATitle;     Position := poScreenCenter;     FormStyle := fsSystemStayOnTop;     Show;     Application.ProcessMessages;     Label1.Caption := AMessage;     Application.ProcessMessages;     Sleep(ADelay);     Close;   end; end; ---------------------------------------------------------------------- jinx · 2010-11-26 17:31 So with that simple procedure it will actually work?! Also is there a possibility of using the notification from KDE? Send messages to KDE notification? ---------------------------------------------------------------------- typo · 2010-11-26 17:36 You need to create formMessage with a Label with WordWrap set to True. ---------------------------------------------------------------------- jinx · 2010-11-26 17:57 How to create a formMessage? ---------------------------------------------------------------------- typo · 2010-11-26 18:05 On the IDE File menu choose New Form. ---------------------------------------------------------------------- jinx · 2010-11-26 18:09 Yeah, but thats now formMessage, its just a form. ---------------------------------------------------------------------- typo · 2010-11-26 18:14 Save it as formMessage, put a label on it, set its size and position, AutoSize to False and its WordWrap to True. ---------------------------------------------------------------------- jinx · 2010-11-26 18:38 Yes sure, I get it, but how am I suppose to build the overall thing and use it in my app? ---------------------------------------------------------------------- typo · 2010-11-26 18:40 Add formMessage's unit to your uses section. ---------------------------------------------------------------------- jinx · 2010-11-26 18:55 Ok so I create a new form and unit, named showmsg.pas. I setup everything, but how do I use or where do I put this procedure: Code: [Select]procedure ShowTheMessage(ATitle, AMessage :string; ADelay :integer); begin   with formMessage do   begin     Caption := ATitle;     Position := poScreenCenter;     FormStyle := fsSystemStayOnTop;     Show;     Application.ProcessMessages;     Label1.Caption := AMessage;     Application.ProcessMessages;     Sleep(ADelay);     Close;   end; end; ---------------------------------------------------------------------- typo · 2010-11-26 19:00 For example: Code: [Select]ShowTheMessage('Title', 'Message', 1000); ---------------------------------------------------------------------- jinx · 2010-11-26 19:03 OK, I know that, use Dialogs,...,showmsg. What am asking is where do I put the ShowTheMessage procedure. ---------------------------------------------------------------------- captian jaster · 2010-11-26 19:06 Quote from: jinx on November 26, 2010, 08:03:41 pmOK, I know that, use Dialogs,...,showmsg. What am asking is where do I put the ShowTheMessage procedure. Where ever you're trying to declare it.. For instance, if you want it to come up when you start the application  put the procedure in the "FormCreate" part Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Procedure TForm1.FormCreate(Sender: TObject)begin   ShowThenMessage('Title','Message',1000);end; ---------------------------------------------------------------------- jinx · 2010-11-26 19:13 No, you don't get it, not how or where to call the procedure when I need it, where to put the actual procedure. I created the new form, named it formMsg, created a label, called Msg, but I'm getting errors: Code: [Select]pigutils.pas(53,31) Error: Identifier not found "poScreenCenter" pigutils.pas(54,35) Error: Identifier not found "fsSystemStayOnTop" pigutils.pas(56,16) Error: Identifier not found "Application" pigutils.pas(58,16) Error: Identifier not found "Application" pigutils.pas(423,39) Hint: Local variable "S" does not seem to be initialized pigutils.pas(428) Fatal: There were 4 errors compiling module, stopping ---------------------------------------------------------------------- typo · 2010-11-26 19:16 You need Controls and Forms on uses section of that unit. Don't put ShowTheMessage procedure on showmsg unit, but on the unit which will call it. ---------------------------------------------------------------------- ivan17 · 2010-11-26 19:23 Quote from: jinx on November 26, 2010, 07:38:26 pmYes sure, I get it, but how am I suppose to build the overall thing and use it in my app? make a form; put a label, timer and a button; invoke it like this (you can wrap these lines into a function): Code: [Select]  MsgForm.Tag := 10; // in seconds   MsgForm.Label1.Caption := 'aasdsa asd asd asd as dasd';   MsgForm.ShowModal; to make it work, double-click the timer and add this into the event handler: Code: [Select]    if Tag = 0 then         Close     else begin         Tag := Tag - 1;         OKButton.Caption := 'OK  (' + IntToStr(Tag) + ')';         Exit;     end assign any modal result to the button;  assign this same handler to the form's OnShow event (in object inspector). you can take care of minor tweaks. ---------------------------------------------------------------------- jinx · 2010-11-26 19:26 Ok, made it work, but it looks really ugly ---------------------------------------------------------------------- typo · 2010-11-26 19:29 Why? ---------------------------------------------------------------------- jinx · 2010-11-26 19:38 I don't know, coz it doesn't look like it suppose to be like that. Just is missing something.... ---------------------------------------------------------------------- jinx · 2010-11-26 19:41 In which unit is ShowModal? ---------------------------------------------------------------------- typo · 2010-11-26 19:44 ShowModal is a method of TForm class. You can improve a bit that procedure by removing formMessage from automatic creation and: Code: [Select]procedure ShowTheMessage(ATitle, AMessage :string; ADelay :integer); begin   Application.CreateForm(TformMessage, formMessage);   with formMessage do   begin     try       Caption := ATitle;       Position := poScreenCenter;       FormStyle := fsSystemStayOnTop;       Show;       Application.ProcessMessages;       Label1.Caption := AMessage;       Application.ProcessMessages;       Sleep(ADelay);     finally       Free;     end;   end; end; ---------------------------------------------------------------------- jinx · 2010-11-26 20:08 Ok it works, but badly. First of all, it takes time to create the "Windows" or "Form" when I use it. Second, I still have on the small form the close button on the title bar, which doesn't work, have to wait for the sleep to stop so the form dies. Also it works the first time, but not the second time. The second time there is no message (Label) anymore, the form is created, but thats it. Code: [Select]Procedure ShowTheMessage(ATitle, AMessage :string; ADelay :integer); Begin   Application.CreateForm(TformMsg, formMsg);   with formMsg do   begin     try       Caption := ATitle;       Position := poScreenCenter;       FormStyle := fsStayOnTop;       Show;       Application.ProcessMessages;       Msg.Caption := AMessage;       Application.ProcessMessages;       Sleep(ADelay);     finally       Free;     end;   end; end; Also the mouse kind of invisible for couple of seconds when the form is "displayed" or "created". ---------------------------------------------------------------------- typo · 2010-11-26 20:24 None of this happens on my test. ---------------------------------------------------------------------- jinx · 2010-11-26 20:29 Well it does in mine and its not very good. ---------------------------------------------------------------------- typo · 2010-11-26 20:32 Probably the same would happen with ShowMessage procedure. You can take off Close button from system menu through property BorderIcons of frmMessage. ---------------------------------------------------------------------- ivan17 · 2010-11-26 20:49 i wanted to type something smart, but with all the problems you are encountering on this simple task, i realized that it is easier to open lazarus, copy into it what i posted above myself, and then send you the zipped code... ---------------------------------------------------------------------- jinx · 2010-11-26 20:54 No possible to use T:\ kind of doesn't work in Linux, if you get my point. Plus it is "maybe" possible the results you have I wont have. Im on Linux with gtk2, Im not sure how compatible is Win with Lin!? ---------------------------------------------------------------------- jinx · 2010-11-26 21:10 Ok, I will re-explain the situation, because maybe I wasn't that precise about it. This app run on Linux and KDE. Until now I was using kdialog to generate some "info" when for example the user was using Search function. Because search doesn't need an "approval" I can't use ShowMessage, so I need to use something which only informs that user that the search is happening and was using: Code: [Select]kdialog --passivepopup "Searching, please wait..." but the issue with this, is that is started by a function in my app, called execute, which after some times end-ups creating zombies of "kdialog". Here is the execute function: Code: [Select]procedure execute (command:string; var output:Tstrings); const   READ_BYTES = 2048; Var  Process :Tprocess;    MemStream : TMemoryStream;   n: LongInt;   BytesRead: LongInt; begin try Process := TProcess.create(nil);;  Process.CommandLine :=  command;  {Actually run the thing and catch the output}   MemStream := TMemoryStream.Create;   outPut := TStringList.Create;   BytesRead := 0;     Process.Options := [poUsePipes,poNoConsole];   Process.Execute;   while Process.Running do   begin     // make sure we have room     MemStream.SetSize(BytesRead + READ_BYTES);     // try reading it     n := Process.Output.Read((MemStream.Memory + BytesRead)^, READ_BYTES);     if n > 0     then begin       Inc(BytesRead, n);     end     else begin       // no data, wait 100 ms       Sleep(100);     end;   end;   // read last part   repeat     // make sure we have room     MemStream.SetSize(BytesRead + READ_BYTES);     // try reading it     n := Process.Output.Read((MemStream.Memory + BytesRead)^, READ_BYTES);     if n > 0     then begin       Inc(BytesRead, n);     end;   until n <= 0;   MemStream.SetSize(BytesRead);   OutPut.LoadFromStream(MemStream);   MemStream.Free;  Process.Free; except       debugln('Could not execute: '+Command); end; end; procedure execute (command:string); {This version just launches without waiting or capturing output} Var  Process :Tprocess; begin try Process := TProcess.create(nil);;  Process.CommandLine :=  command;   Process.Options := [poNoConsole];   Process.Execute;  Process.Free; except       debugln('Could not execute: '+Command); end; end; Now I would like a function/procedure which send this message, if possible to KDE notification and appears at the taskbar. The procedure that you guys mentioned is ok, but is slow and has a lot of issues, ok, maybe it's me, because I haven't use pascal/lazarus in like 10 years ---------------------------------------------------------------------- jinx · 2010-11-26 21:20 Check the attachment, its an example of what I mean. ---------------------------------------------------------------------- ivan17 · 2010-11-26 22:23 Quote from: jinx on November 26, 2010, 09:54:29 pmNo possible to use T:\ kind of doesn't work in Linux, if you get my point. no i don't.  it is fully platform independent.  you just don't want to spend more than a second on things. fix or delete the config file from the archive. ---------------------------------------------------------------------- typo · 2010-11-26 22:40 Try attached. ---------------------------------------------------------------------- jinx · 2010-11-26 22:47 Can't build it: Unit2.pas(44,1) Error: resource compiler not found, switching to external mode ---------------------------------------------------------------------- typo · 2010-11-26 23:26 Try another one. ---------------------------------------------------------------------- jinx · 2010-11-26 23:30 LOL! Same issue Im must be the most unlucky lazarus user ever Told u win stuff wont work well on linux stuff! ---------------------------------------------------------------------- typo · 2010-11-26 23:39 Copy the files to a project made on your computer. ---------------------------------------------------------------------- jinx · 2010-11-26 23:42 I get the idea of it, but I can't use ur idea in my app, at least not in the same way, anyway. ---------------------------------------------------------------------- jinx · 2010-11-27 10:45 So nothing? ---------------------------------------------------------------------- jinx · 2010-11-27 18:19 OK, lets forget about creating a new form, but I would like to fix one thing when using "kdialog". Note this is for Linux/KDE, not windows. Here is whats happening when using "execute" procedure: Code: [Select]kongoni  11353 25958  0 19:15 ?        00:00:00 [kdialog] kongoni  11638 25958  0 19:15 ?        00:00:00 [kdialog] kongoni  12341 25958  2 19:16 ?        00:00:00 [kdialog] For some reason, until my pass is not killed those zombies are not going away, plus they will be many more depending on the apps usage. So can anyone check the procedure execute which I wrote in a previous post? ---------------------------------------------------------------------- garlar27 · 2010-11-29 12:28 Quote from: jinx on November 27, 2010, 12:30:49 amTold u win stuff wont work well on linux stuff!    Don't hesitate! We all know that windows' stuff don't work on linux but, FPC and Lazarus are cross platform and we share the same code between different OSs.    So the first attempt is to do it the cross-platform way (a form on scrren center with a text and a caption and no buttons) which can be implemented in various ways and would need a little tweak to achieve the desired "flavor".    but if you if you are having problems to fit your needs and you are short of time you can use the ugly, and muddy shortcut by executing an external app or an OS command with: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i ExecuteProcess(Application.Location, 'kdialog --passivepopup "Searching, please wait..."'); You can find more info about "ExecuteProcess" on the Wiki