Solved

Application.ProcessMessages;

Posted on 2002-07-14
19
425 Views
Last Modified: 2010-04-04
Simple, Without calling Application.ProcessMessages; is it possible to check any input for 1 window?  so for example
a routine is going from 1 to 100000 in a tight loop and you want to be able to type out in for example memo1 while the loop is going on i would call App.Proces (To allow user input)....  is there a way to allow the program to keep checking for Keyboard input for that 1 window (Memo1)?

Thanks All..

Craig C.
0
Comment
Question by:craig_capel
  • 8
  • 3
  • 3
  • +3
19 Comments
 
LVL 20

Expert Comment

by:Madshi
ID: 7152793
Theoretically I'm already sleeping, but let me at least name the APIs: Both PeekMessage (non-blocking) and GetMessage (blocking) lets you define a filter of messages that you want to get. You can define which window should be checked and which message range. Then call TranslateMessage and DispatchMessage. Sorry, too tired to write code...
0
 
LVL 7

Expert Comment

by:Cynna
ID: 7152810
This is the code:

procedure MyProcessMessages;
var Msg : TMsg;
begin
    while PeekMessage(Msg, 0, 0, 0, PM_REMOVE ) do begin
      if  Msg.Message = 0 then begin // WM_QUIT
          PostQuitMessage(msg.wparam);
          Application.Terminate;
          Exit;
      end
      else begin
          TranslateMessage(Msg);
          DispatchMessage(Msg);
      end;
    end;
    Sleep(1);
end;
0
 
LVL 3

Expert Comment

by:smurff
ID: 7152835
listening
0
 
LVL 2

Author Comment

by:craig_capel
ID: 7152980
Hmm right so i can not do something like..

Memo.ProcessAnyMessagesWaitingForThisWindowOnly;

and leave all the rest? - what it is, is this: the chat client is constantly getting data and putting it out to the chat screen, if you are typing it pauses while it updates Richedit, on lots of data u may be stopped from typing up to about 1 - 2 seconds. If i can process just the memo to keep letting it recieve system messages and nothing else at all i will be fine (app. calls system messages for the whole program which causes problems)

Thanks

Craig C.
0
 
LVL 7

Expert Comment

by:Cynna
ID: 7153048
Just replace second 0 in PeekMessage with window handle (look at the API help for PeekMessage).

Like this:

procedure ProcessWindowMessages(WindowHandle: Hwnd);
var Msg : TMsg;
begin
   while PeekMessage(Msg, WindowHandle, 0, 0, PM_REMOVE ) do begin
     if  Msg.Message = 0 then begin // WM_QUIT
         PostQuitMessage(msg.wparam);
         Application.Terminate;
         Exit;
     end
     else begin
         TranslateMessage(Msg);
         DispatchMessage(Msg);
     end;
   end;
   Sleep(1);
end;


So, this will process messages for Memo1 only (everything else is freezed):

ProcessWindowMessages(Form1.Memo1.Handle);

0
 
LVL 2

Author Comment

by:craig_capel
ID: 7153055
Hmm right so i can not do something like..

Memo.ProcessAnyMessagesWaitingForThisWindowOnly;

and leave all the rest? - what it is, is this: the chat client is constantly getting data and putting it out to the chat screen, if you are typing it pauses while it updates Richedit, on lots of data u may be stopped from typing up to about 1 - 2 seconds. If i can process just the memo to keep letting it recieve system messages and nothing else at all i will be fine (app. calls system messages for the whole program which causes problems)

Thanks

Craig C.
0
 
LVL 2

Author Comment

by:craig_capel
ID: 7153069
Hmm right so i can not do something like..

Memo.ProcessAnyMessagesWaitingForThisWindowOnly;

and leave all the rest? - what it is, is this: the chat client is constantly getting data and putting it out to the chat screen, if you are typing it pauses while it updates Richedit, on lots of data u may be stopped from typing up to about 1 - 2 seconds. If i can process just the memo to keep letting it recieve system messages and nothing else at all i will be fine (app. calls system messages for the whole program which causes problems)

Thanks

Craig C.
0
 
LVL 2

Author Comment

by:craig_capel
ID: 7153071
Stupid Netscape (Netscape seems to post the very last thing you did every 10 - 15 minutes on it's own)

0
 
LVL 2

Author Comment

by:craig_capel
ID: 7153138
Stupid Netscape (Netscape seems to post the very last thing you did every 10 - 15 minutes on it's own)

0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
LVL 2

Expert Comment

by:mullet_attack
ID: 7153497
is your chat client actively checking for data, then displaying in the memo? from what you said, it would seem to be the case.

If so, read on, otherwise ignore me....

two possibilities:
does your TCP/socket/pipe/whatever that receives the data have some sort of OnReceivedData event? If so, then you only update the memo when data is received, and nothing gets blocked.

if not, then I suggest
a. use a componenst that has a Rxdata event, or
b. if you really need to continually check for received data, do it in a separate thread, thats what they're for.
0
 
LVL 2

Author Comment

by:craig_capel
ID: 7153605
The problem is this.

1. Program looks for incoming chat data (onRead) If any data exists it passes it to
    DealwithChatData(DataString: String);
2. For D:=1 to Length(DataString) Do DisplayStr(DataString[n],differentcolorsforeachchar);

Richedit is slow when it comes to changing colors so in order to make the program not lock up
for that duration of time i would do Application.ProcessMessages; but while displaying the string it
would check for more chat data, or any user input from the memo and then call the routine to display it again, which causes Chat text to merge with other lines.

Is it possible to put a Memo into it's own thread so it can constantly check for messages and not stop responding when doing a cpu intensive routine?

Cynna - thank you and i checked the code but for some reason all the other windows seem to active when i click on them i think i need to read up more on how delphi handles messages.
0
 
LVL 3

Expert Comment

by:LukA_YJK
ID: 7153655
Maybe you should exchange data in a new different thread...
0
 
LVL 20

Expert Comment

by:Madshi
ID: 7153668
Another thread could be a solution.

Hmmm... Are you using the RichEdit in ReadOnly mode? Just to show something? In that case you might want to use a faster component. I might have something for you then.

But does really *each and every* char have a different color??? I can't see the sense of that. Probably some words or sentences have a different color, right? You should try to add words or sentences to the text component, that's much MUCH faster...

Regards, Madshi.
0
 
LVL 2

Expert Comment

by:mullet_attack
ID: 7153737
is the Onread an event of some sort of comms component? if so, what do you mean by "so it can constantly check for messages "
0
 
LVL 2

Author Comment

by:craig_capel
ID: 7155137
Madashi, http://www.lagmaster.net/~ymlite/screenshot.gif <<is actually a screen shot of it in action, and no not all chars are different colors, i even wrote a routine to make the fade more blocky so instead of a smooth fade to a rougher fade but really the problem on comes into play after 400 - 500 lines in richedit, to start with u can not see the program halting while displaying text, on around 1000 - 1500 the controls stop respoding for a brief moment in time while it's displaying text to the screen and so on and so fourth.

1 - 300 lines Richedit is perfect no delay (no need to do anything)
300 - 600 lines When a line gets outputting with SelText it then starts to slow down
600 - 1000 lines the delay gets longer even to do output of text
2000 - 3000 lines just to display "hello there" causes it to stop for almost a second

I don't do anything differently just the more text Richedit gets the slower it gets to output
which in turn causes the program to lockup for longer which is annoying if you are trying to type something and everytime data comes in, nothing appears to the screen until it's stopped then a second later text stops again - it's just annoying. as soon as i
use Application.ProcessMessages; it fixes it but it also merges text (can) as it goes and outputs new text it found from onread (while still completing the old routine) .

Before every post i do this..

Richedit.SelStart:=-1;  <<moving the cursor to the bottom to then do
SelText:=Username;
SelText:=': ';
SelText:=Message; if it's a incoming fade it simply parses out what's needed and does what i needs.

If i have to i will simply not check for any messages as it does slow the routine down :(
(how it is now)

http://www.lagmaster.net/~ymlite/index.html  is the Chat Client's homepage.
0
 
LVL 2

Expert Comment

by:mullet_attack
ID: 7155730
craig,
I wouldn't use a richedit for this, as once you have received the data, you don't edit it, so all the editting power of the richedit is wasted. unfortunatly, it's that inbuilt editing code/design that makes it so sloooooow

this is what I would try:

PLineInfo = ^TLineInfo;
  TLineInfo = record
color : TColor:
flashing : boolean;
// whatever other line attributes you want
end;

create your own stringlist, to which you add each line of incoming data.
When you add the text to the stringlist, do this :

var
LineInfoPtr : PLineInfo;
//
begin
// etc...
New(LineInfoPtr);
LineInfoPtr^.Color := clWhateverColorYouWant;
LineInfoPtr^.Flashing := false; // whatever... :-)
MyStringList.addObject(TheText, LineInfoPtr);


use a canvas of some sort to draw the text your self, instead of the rich edit
by using the position of a scroll bar, you know the top line that is visible, and the by height of your canvas you know the number of lines, so

for t := TopLine to TopLine + NumberOFLines do
  begin
  canvas.font.color := PLineInfo(MyStringList.Objects[t])^.Color;
  TextOut(X,t * LineHeight,MyStringList.strings[t]);
//etc...

I would double-buffer the whole thing, whereby you do the actual textout stuff to an off screen canvas, then bitblt the whole canvas to the on-screen one, to avoid that irritating flicker

I know this looks like hard work, but the result will  lightning fast, without having to resort to dodgy hacks to make it work.

Good luck,
Mark

0
 
LVL 3

Accepted Solution

by:
LukA_YJK earned 50 total points
ID: 7158813
Very impressive, Craig !
I liked your chat client (screeshot at least) I have two ideas:
1) As it wrote in Help: "It is a good idea to include the client socket object in a thread if the ClientType is ctBlocking, so that I/O does not block all execution within the client application."
2) Regarding RichEdit, as I understood you make the color thing in a loop. But maybe you can first construct all the colored text and then paste it into RichEdit at once... How ? As you know there is a clipboard format CF_RTF and I think actually RichEdit stores text in RTF format. Maybe you can construct a string corresponding to a RTF code of colored text. Something like Format('{\colortbl ;\red%d\green%d\blue%d;} %s', [R, G, B, str]) You can find exact definition at www.wotsit.org. Then paste it to RichEdit sending EM_PASTE message using PostMessage.
Hope it will be helpful... eh, maximum I'll win will be 50 points anyway ;)
0
 
LVL 2

Author Comment

by:craig_capel
ID: 7160556
Yup thanks that was the best way, SelAttribs is slow so building up the string then displaying it was much faster - thanks.
0
 
LVL 3

Expert Comment

by:LukA_YJK
ID: 7161655
Thanks, Craig ! Hey, you gave me 200 points ! Yay, my second 200 points ;) I'm really happy... also because I could help you in development of such a super-duper chat client !
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
When you create an app prototype with Adobe XD, you can insert system screens -- sharing or Control Center, for example -- with just a few clicks. This video shows you how. You can take the full course on Experts Exchange at http://bit.ly/XDcourse.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now