Link to home
Start Free TrialLog in
Avatar of craig_capel
craig_capel

asked on

Application.ProcessMessages;

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.
Avatar of Madshi
Madshi

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...
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;
listening
Avatar of craig_capel

ASKER

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.
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);

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.
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.
Stupid Netscape (Netscape seems to post the very last thing you did every 10 - 15 minutes on it's own)

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

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.
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.
Maybe you should exchange data in a new different thread...
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.
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 "
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.
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

ASKER CERTIFIED SOLUTION
Avatar of LukA_YJK
LukA_YJK
Flag of Azerbaijan image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Yup thanks that was the best way, SelAttribs is slow so building up the string then displaying it was much faster - thanks.
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 !