PostMessage() error

  • Thread starter Thread starter one2001boy
  • Start date Start date
O

one2001boy

PostMessage() function returns ERROR_NOT_ENOUGH_QUOTA after running in a
loop for 700 times, but the disk space and memory are still big enough.

any suggestion to resolve this problem?
thanks.
 
PostMessage() function returns ERROR_NOT_ENOUGH_QUOTA after running in a
loop for 700 times, but the disk space and memory are still big enough.

That sounds like a safety limit to prevent excessive numbers of
messages. In normal circumstances it would seem to indicate that
you're trying to post messages to a window that's not processing
messages.
any suggestion to resolve this problem?

Don't do it.
Allow the other application to run and process its messages.

Dave
 
PostMessage() function returns ERROR_NOT_ENOUGH_QUOTA after running in a
loop for 700 times, but the disk space and memory are still big enough.

any suggestion to resolve this problem?
thanks.

Why are you trying this measurement? What are you trying to do?
Windows GUI messages are aimed at GUI/window interacting. Usually,
hitting those limits means you are subverting the GUI messaging system
to do something else, something it wasn't designed for.

Eg, I have seen acquistion loops or the like using PostMessage. Don't
do it!

Arnaud
MVP - VC
 
David said:
That sounds like a safety limit to prevent excessive numbers of
messages. In normal circumstances it would seem to indicate that
you're trying to post messages to a window that's not processing
messages.

here is the sample code. I removed createprocess() function.

int main()
{
....
while (fgets(psBuffer, BUFFER_SIZE, stdin) != NULL) {
PostString(hwndText, psBuffer);
}
....}


void
PostString(HWND hwnd, char *pc)
{
while(*pc) {
PostMessage(hwnd, WM_CHAR, (unsigned char) *pc, 1L);
pc++;
}
}

it get the problem of ERROR_NOT_ENOUGH_QUOTA for the function of
PostMessage() after processing 4k of stdin piped data ( I have 14K of
stdin data to process)

do you think 14k of stdio piped data is too big for PostMessage()?

thanks.
 
Why are you trying this measurement? What are you trying to do?
Windows GUI messages are aimed at GUI/window interacting. Usually,
hitting those limits means you are subverting the GUI messaging system
to do something else, something it wasn't designed for.

Eg, I have seen acquistion loops or the like using PostMessage. Don't
do it!

See my answer to David. Thanks.
 
it get the problem of ERROR_NOT_ENOUGH_QUOTA for the function of
PostMessage() after processing 4k of stdin piped data ( I have 14K of
stdin data to process)

do you think 14k of stdio piped data is too big for PostMessage()?

The issue is not so much about PostMessage() as it is about the queue of
messages in the target application. The function deposits a message in the
queue and returns. If you have a big buffer, on a fast machine, what's
happening is that your application is posting messages for the whole of its
timeslice while the receiver has no chance to drain the queue.

You need to switch to a better method of IPC - perhaps SendInput() as I
suggested in another thread - or you need to block the sender periodically -
perhaps with WaitForInputIdle() specifying the receiver's process handle.

Regards,
Will
 
William said:
The issue is not so much about PostMessage() as it is about the queue of
messages in the target application. The function deposits a message in the
queue and returns. If you have a big buffer, on a fast machine, what's
happening is that your application is posting messages for the whole of its
timeslice while the receiver has no chance to drain the queue.

You need to switch to a better method of IPC - perhaps SendInput() as I
suggested in another thread - or you need to block the sender periodically -
perhaps with WaitForInputIdle() specifying the receiver's process handle.

Regards,
Will

the pipe is for a file not for keyboard typed characters,
it runs such as
executable.exe < piped_file
or use fopen() to open the file and send to windows GUI appications

SendInput() might not be suitable for my case.

thanks.
 
the pipe is for a file not for keyboard typed characters,

Then why are you sending WM_CHAR messages? Those messages are in general
synthesized by Windows when it encounters WM_KEYUP and WM_KEYDOWN messages
in the queue and those are generated in response to user keystrokes.
SendInput() might not be suitable for my case.

I don't know what you are trying to do, but SendInput() was practically
invented so that you don't have to send WM_CHAR messages which is a bad
idea. You have to understand that the WM_CHAR messages are intended to be
used for input to controls like edit boxes in cases where the user is typing
away at the keyboard.

What I suspect you are doing is well beyond the pale in that it looks like
you are stuffing several KB of keystrokes into what might be called "type
ahead buffer" on another platform.

Regards,
Will
 
William said:
Then why are you sending WM_CHAR messages? Those messages are in general
synthesized by Windows when it encounters WM_KEYUP and WM_KEYDOWN messages
in the queue and those are generated in response to user keystrokes.

I think the original author wants to be able to use keyboard input as
well. but for my use, I will use it to read from a file to redirect to
a windows GUI application.

I just read the link from
http://msdn.microsoft.com/library/d...agesandmessagequeuesfunctions/postmessage.asp

it looks that I only need to modify the registry value for windows
2000/XP for

HKEY_LOCAL_MACHINE->SOFTWARE->Microsoft->Windows
NT->CurrentVersion->Windows->USERPostMessageLimit

HOwever, there is no such a registry value under windows XP,

I modified

HKEY_LOCAL_MACHINE->SOFTWARE->Microsoft->Windows
NT->CurrentVersion->Windows->USERProcessHandleQuota ,
increase it from 10000 to 30000. it doesn't seem to work.

Then, I add the registry value for USERPostMessageLimit as requested,
run the program again, it still has the same problem.

If I change the PostMessage() function to SendInput(), do I need to
modify windows GUI applications to recieve the data?

thanks.
 
First, I have no idea what it your application is doing, but second WM_CHAR
is a message which most definitely has to do with characters typed by a
user. There are times when applications create these messages in a hokey way
to simulate a user at a keyboard but you should not expect this to work
reliably. For that SendInput() is usually a better choice.

What class of window is the one to which you are sending the WM_CHAR
messages?
it looks that I only need to modify the registry value for windows
2000/XP for

HKEY_LOCAL_MACHINE->SOFTWARE->Microsoft->Windows
NT->CurrentVersion->Windows->USERPostMessageLimit

HOwever, there is no such a registry value under windows XP,

I modified

HKEY_LOCAL_MACHINE->SOFTWARE->Microsoft->Windows
NT->CurrentVersion->Windows->USERProcessHandleQuota ,
increase it from 10000 to 30000. it doesn't seem to work.

OMG. I tried to explain in a previous message why I thought you were having
a problem and what you needed to do. As I see it, nothing good will come of
hacking the registry.

Regards,
Will
 
See my answer to David. Thanks.

William and I are trying to explain you that you are probably not using
the right mechanism (eg, PostMessage) for what you want to do....

Would you mind explaining us what is your real goal, without digging
into the low-level registry settings for message queues?
You are trying to send a 14Ko file from one app to another, right? Why
are you using PostMessage(WM_CHAR) instead of a pipe or another IPC
mechanism? Please give us some background information, so that we can
better advise you. Anyway, windows message queues are NOT designed for
this kind of data exchange...

Arnaud
MVP - VC
 
Why are you trying this measurement? What are you trying to do?
Windows GUI messages are aimed at GUI/window interacting. Usually,
hitting those limits means you are subverting the GUI messaging system
to do something else, something it wasn't designed for.

Seems to me it is not an error condition, but an expected state (the queue
is full), and you need to treat the failure as a form of flow control. You
wouldn't expect to be able to send one million packets out a socket either
without a delay.
Eg, I have seen acquistion loops or the like using PostMessage. Don't
do it!

Curious to know what you would use, considering COM, DCOM, ActiveX, MTS, etc
all are built on top of SendMessage/PostMessage.
 
Ben Voigt said:
Seems to me it is not an error condition, but an expected state (the queue
is full), and you need to treat the failure as a form of flow control.
You wouldn't expect to be able to send one million packets out a socket
either without a delay.

Of course, but windows messages queues are not particualry efficient, nor
designed to exchange many data. There are many other available options.

For example, it is just a bad idea to try to record from a sound card using
PostMessage to transmit samples : this will most certainly overflows message
queues very quickly... yet any decent PC can record from it's sound card
with almost no CPU load, if done correctly.
Curious to know what you would use, considering COM, DCOM, ActiveX, MTS,
etc all are built on top of SendMessage/PostMessage.

DCOM is not built on top of PostMessage but over RPC (otherwise, it won't
work over a network).

COM uses PostMessage only in STA context, and this is mainly for historical
(bad) reasons : old VB versions were unable to spawn worker threads, and
thus messages needed to be posted to the GUI thread.

ActiveX are just COM object, so the COM/DCOM remarks applie.

I don't know about MTS.

Anyway, for heavy duty data exchange, I would probably use DCOM / Pipe /
Socket / Shared memory (MMF) / .NET Remoting depending on the exact context.
In any case, I would most probably have a dedicated thread waiting on the
data queue, not the GUI thread.

Arnaud
MVP - VC
 
William and I are trying to explain you that you are probably not using
the right mechanism (eg, PostMessage) for what you want to do....

I really appreciate you and william's help.

here is the code I write to take advantage of pgnuplot.exe, it will open
a file "data" with 14k size to send to pgnuplot.exe

#include <stdio.h>
#include <stdlib.h>

#define BUFSIZE 1024
int main() {
FILE *pPipe;
FILE *fp1;
char line[BUFSIZE];

pPipe = _popen("c:\\gnuplot\\bin\\pgnuplot.exe -persist", "w" );

if((fp1 = fopen("data", "r")) == NULL)
return -1;
fgets(line, BUFSIZE, fp1);
while(!feof(fp1)) {
fputs(line, pPipe);
fgets(line, BUFSIZE, fp1);
}
fclose(fp1);
printf( "\nProcess returned %d\n", _pclose( pPipe ) );
return 0;
}

pgnuplot.exe is a another pipe to windows GUI wgnuplot.exe.
Here is the code for pgnuplot.c which compiles and get pgnuplot.exe.
the code inside pgnuplot.c contains function PostMessage(), and this
function causes the problem from what I tested.

source code for pgnuplto.c, the comments are also left here for your
reference.

#ifndef lint
static char *RCSid() { return RCSid("$Id: pgnuplot.c,v 1.15 2006/04/08
14:22:48 mikulik Exp $"); }
#endif

/*
* pgnuplot.c -- pipe stdin to wgnuplot
*
* Version 0.4 -- October 2002
*
* Compile pgnuplot by:
* gcc -O2 -s -o pgnuplot.exe pgnuplot.c ../version.c -I.. -luser32
*/

/* Comments from original pgnuplot.c */
/*
* pgnuplot.c -- 'Pipe to gnuplot' Version 990608
*
* A small program, to be compiled as a Win32 console mode application.
* (NB: will not work on 16bit Windows, not even with Win32s installed).
*
* This program will accept commands on STDIN, and pipe them to an
* active (or newly created) wgnuplot text window. Command line options
* are passed on to wgnuplot.
*
* Effectively, this means `pgnuplot' is an almost complete substitute
* for `wgnuplot', on the command line, with the added benefit that it
* does accept commands from redirected stdin. (Being a Windows GUI
* application, `wgnuplot' itself cannot read stdin at all.)
*
* Copyright (C) 1999 by Hans-Bernhard Broeker
*
* Changes relative to that original version:
* -- doesn't start a new wgnuplot if one already is running.
* -- doesn't end up in an endless loop if STDIN is not redirected.
* (refuses to read from STDIN at all, in that case).
* -- doesn't stop the wgnuplot session at the end of
* stdin, if it didn't start wgnuplot itself.
* -- avoids the usual buffer overrun problem with gets().
*


Major changes: (See the explanation below for more information)
+ Always starts a new instance of wgnuplot.
+ If stdin isn't redirected then start wgnuplot and give it focus.
+ Uses CreateProcess() instead of WinExec() to start wgnuplot when stdin
is redirected.

Other changes:
+ New technique for building the command line to pass to wgnuplot.exe
which is less complicated and seems to work more reliably than the old
technique.
+ Simplified message passing section of the code.
+ All printf(...) statements are now fprintf(stderr,...) so that errors
are sent to the console, even if stdout is redirected.

The previous version of pgnuplot would fail when more than one program
tried to access wgnuplot simultaneously or when one program tried to start
more than one wgnuplot session. Only a single instance of wgnuplot would be
started and all input would be sent to that instance. When two or more
programs
tried to pipe input to wgnuplot, the two seperate input streams would
be sent
to one wgnuplot window resulting in one very confused copy of wgnuplot.
The only
way to avoid this problem was to change pgnuplot so that it would start a
new instance of wgnuplot every time.

Just starting a new instance of wgnuplot isn't enough. pgnuplot must also
make sure that the data on each stdin pipe is sent to the proper wgnuplot
instance. This is achieved by using CreateProcess() which returns a handle
to the newly created process. Once the process has initialized, it can be
searched for the text window and then data can be routed correctly. The
search
is carried out by the EnumThreadWindows() call and the data passing is
carried
out by a rewritten version of the original code. With these changes,
pgnuplot
now behaves in a manner consistent with the behavior of gnuplot on UNIX
computers.

This program has been compiled using Microsoft Visual C++ 4.0 with the
following command line:

cl /O2 pgnuplot.c /link user32.lib

The resulting program has been tested on WinNT and Win98 both by calling
it directly from the command line with and without redirected input. The
program also works on WinNT with a modified version of Gnuplot.py (a script
for interactive control of Gnuplot from Python).

22 JUN 1999:
+ Fixed command line code to behave properly when the first
item is quoted in the original command line.

29 JUN 1999:
+ Added some code to print the command line. This is for testing
only and should be removed before the general release. To enable,
compile with SHOWCMDLINE defined.

30 JUN 1999:
+ New function FindUnquotedSpace() which replaces the earlier technique for
finding the command line arguments to send on to wgnuplot. Prior to this
the arguments were assumed to start after argv[0], however argv[0] is not
set the same by all combinitaions of compiler, command processor, and OS.
The new method ignores argv completely and manually search the
command line
string for the first space which isn't enclosed in double-quotes.

*/

#include <io.h>
#include <conio.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include "version.h"

#ifndef _O_BINARY
# define _O_BINARY O_BINARY
#endif
#if (__BORLANDC__ >= 0x450) /* about BCBuilder 1.0 */
# define _setmode setmode
#endif
#ifdef __WATCOMC__
# define _setmode setmode
#endif

/* Customize this path if needed */
#define PROGNAME "wgnuplot.exe"
/* CRS: The value given above will work correctly as long as pgnuplot.exe
* is in the same directory as wgnuplot.exe or the directory containing
* wgnuplot.exe is included in the path. I would recommend placing the
* pgnuplot.exe executable in the same directory as wgnuplot.exe and
* leaving this definition alone.
*/

#define WINDOWNAME "gnuplot"
#define PARENTCLASS "wgnuplot_parent"
#define TEXTCLASS "wgnuplot_text"
#define GRAPHWINDOW ""
#define GRAPHCLASS "wgnuplot_graph"
#define BUFFER_SIZE 80

/* GLOBAL Variables */
HWND hwndParent = NULL;
HWND hwndText = NULL;

PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;

/* CRS: Callback for the EnumThreadWindows function */
BOOL CALLBACK
cbGetTextWindow(HWND hwnd, LPARAM lParam)
{
/* save the value of the parent window */
hwndParent = hwnd;
/* check to see if it has a child text window */
hwndText = FindWindowEx(hwnd, NULL, TEXTCLASS, NULL);

/* if the text window was found, stop looking */
return (hwndText == NULL);
}

/* sends a string to the specified window */
/* CRS: made this into a function call */
void
PostString(HWND hwnd, char *pc)
{
while(*pc) {
PostMessage(hwnd, WM_CHAR, (unsigned char) *pc, 1L);
/* CRS: should add a check of return code on PostMessage. If 0, the
message que was full and the message wasn't posted. */
pc++;
}
}

/* FindUnquotedSpace(): Search a string for the first space not enclosed
in quotes.
* Returns a pointer to the space, or the empty string if no space is
found.
* -CRS 30061999
*/
char*
FindUnquotedSpace(char *pc)
{
while ((*pc) && (*pc != ' ') && (*pc != '\t')) {
if (*pc == '"') {
do {
pc++;
} while (pc[1] && (*pc != '"'));
}
pc++;
}
return pc;
}

int
main (int argc, char *argv[])
{
char psBuffer[BUFFER_SIZE];
char psGnuplotCommandLine[MAX_PATH] = PROGNAME;
LPTSTR psCmdLine;
BOOL bSuccess;
BOOL bPersist = FALSE;
int i;

#if !defined(_O_BINARY) && defined(O_BINARY)
# define _O_BINARY O_BINARY
# define _setmode setmode /* this is for BC4.5 ... */
#endif
_setmode(fileno(stdout), _O_BINARY);

for (i = 1; i < argc; i++) {
if (!argv)
continue;
if (!strcmp(argv, "-V") || !strcmp(argv, "--version")) {
printf("gnuplot %s patchlevel %s\n",
gnuplot_version, gnuplot_patchlevel);
return 0;
} else if ((!stricmp(argv, "-noend")) || (!stricmp(argv,
"/noend")) ||
(!stricmp(argv, "-persist"))) {
bPersist = TRUE;
} else if (!strcmp(argv, "-h") || !strcmp(argv, "--help")) {
printf("Usage: gnuplot [OPTION] [FILE] [-]\n"
" -V, --version show gnuplot version\n"
" -h, --help show this help\n"
" -persist don't close the plot after executing FILE\n"
" -noend, /noend like -persist (non-portable Windows-only
options)\n"
" - allow work in interactive mode after executing
FILE\n"
"Only on Windows, -persist and - have the same effect.\n"
"This is gnuplot %s patchlevel %s\n"
"Report bugs to <[email protected]>\n",
gnuplot_version, gnuplot_patchlevel);
return 0;
}
} /* for(argc) */

/* CRS: create the new command line, passing all of the command
* line options to wgnuplot so that it can process them:
* first, get the command line,
* then move past the name of the program (e.g., 'pgnuplot'),
* finally, add what's left of the line onto the gnuplot command
line. */
psCmdLine = GetCommandLine();

#ifdef SHOWCMDLINE
fprintf(stderr,"CmdLine: %s\n", psCmdLine);
fprintf(stderr,"argv[0]: %s\n",argv[0]);
#endif

/* CRS 30061999: Search for the first unquoted space. This should
separate the program name from the arguments. */
psCmdLine = FindUnquotedSpace(psCmdLine);

strncat(psGnuplotCommandLine, psCmdLine, MAX_PATH -
strlen(psGnuplotCommandLine));

#ifdef SHOWCMDLINE
fprintf(stderr,"Arguments: %s\n", psCmdLine);
fprintf(stderr,"GnuplotCommandLine: %s\n",psGnuplotCommandLine);
#endif

/* CRS: if stdin isn't redirected then just launch wgnuplot normally
* and exit. */
if (isatty(fileno(stdin))) {
if (WinExec(psGnuplotCommandLine, SW_SHOWDEFAULT) > 31) {
exit(EXIT_SUCCESS);
}
fprintf(stderr,"ERROR %u: Couldn't execute: \"%s\"\n",
GetLastError(), psGnuplotCommandLine);
exit(EXIT_FAILURE);
}

/* CRS: initialize the STARTUPINFO and call CreateProcess(). */
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.lpReserved = NULL;
siStartInfo.lpReserved2 = NULL;
siStartInfo.cbReserved2 = 0;
siStartInfo.lpDesktop = NULL;
siStartInfo.dwFlags = STARTF_USESHOWWINDOW;
siStartInfo.wShowWindow = SW_SHOWMINIMIZED;

bSuccess = CreateProcess(
NULL, /* pointer to name of executable module */
psGnuplotCommandLine, /* pointer to command line string */
NULL, /* pointer to process security attributes */
NULL, /* pointer to thread security attributes */
FALSE, /* handle inheritance flag */
0, /* creation flags */
NULL, /* pointer to new environment block */
NULL, /* pointer to current directory name */
&siStartInfo, /* pointer to STARTUPINFO */
&piProcInfo /* pointer to PROCESS_INFORMATION */
);

/* if CreateProcess() failed, print a warning and exit. */
if (! bSuccess) {
fprintf(stderr,"ERROR %u: Couldn't execute: \"%s\"\n",
GetLastError(), psGnuplotCommandLine);
exit(EXIT_FAILURE);
}

/* CRS: give gnuplot enough time to start (1 sec.) */
if (WaitForInputIdle(piProcInfo.hProcess, 1000)) {
fprintf(stderr, "Timeout: gnuplot is not ready\n");
exit(EXIT_FAILURE);
}

/* CRS: get the HWND of the parent window and text windows */
EnumThreadWindows(piProcInfo.dwThreadId, cbGetTextWindow, 0);

/* CRS: free the process and thread handles */
CloseHandle(piProcInfo.hProcess);
CloseHandle(piProcInfo.hThread);

if (! hwndParent || ! hwndText) {
/* Still no gnuplot window? Problem! */
fprintf(stderr, "Can't find the gnuplot window");
exit(EXIT_FAILURE);
}

/* wait for commands on stdin, and pass them on to the wgnuplot text
* window */
while (fgets(psBuffer, BUFFER_SIZE, stdin) != NULL) {
PostString(hwndText, psBuffer);
}

/* exit gracefully, unless -persist is requested */
if (!bPersist) {
/* CRS: Add a test to see if gnuplot is still running? */
PostString(hwndText, "\nexit\n");
}

return EXIT_SUCCESS;
}


thanks.
 
I really appreciate you and william's help.

here is the code I write to take advantage of pgnuplot.exe, it will open
a file "data" with 14k size to send to pgnuplot.exe

I've made the minimum change that might fix your problem:

/* sends a string to the specified window */
/* CRS: made this into a function call */
void
PostString(HWND hwnd, char *pc)
{
int i = 0;

while(*pc) {
if ((i % 100) == 0)
{
//wait for idle every 100 characters, and every line
if (WaitForInputIdle(piProcInfo.hProcess, 1000))
{
fprintf(stderr, "Timeout: gnuplot is too busy\n");
exit(EXIT_FAILURE);
}
}
PostMessage(hwnd, WM_CHAR, (unsigned char) *pc, 1L);
/* CRS: should add a check of return code on PostMessage. If 0, the
message que was full and the message wasn't posted. */
pc++;
++i;
}
}

Tom
 
Tom said:
I've made the minimum change that might fix your problem:

/* sends a string to the specified window */
/* CRS: made this into a function call */
void
PostString(HWND hwnd, char *pc)
{
int i = 0;

while(*pc) {
if ((i % 100) == 0)
{
//wait for idle every 100 characters, and every line
if (WaitForInputIdle(piProcInfo.hProcess, 1000))
{
fprintf(stderr, "Timeout: gnuplot is too busy\n");

Just tested your solution.

the code got in here and exited. I changed 1000 characteres to
10000 characters, it still doesn't work.

is there a way to prevent timeout?

thanks.
 
Just tested your solution.

the code got in here and exited. I changed 1000 characteres to
10000 characters, it still doesn't work.

is there a way to prevent timeout?

If you've given GNUPlot lots of work to do, you might need to wait for a
long time I suppose. You could try:
if (WaitForInputIdle(piProcInfo.hProcess, INFINITE))

An alternative and unreliable hack would be to just carry on and not
call exit (e.g. delete the line exit(EXIT_FAILURE);).


Incidentally, rather than piping the command file to pgnuplot (which is
causing problems, since that doesn't seem to be what pgnuplot was
designed for), why not just pass the name of the command file as a
command line parameter to wgnuplot (or pgnuplot)?

Tom
 
Tom said:
If you've given GNUPlot lots of work to do, you might need to wait for a
long time I suppose. You could try:
if (WaitForInputIdle(piProcInfo.hProcess, INFINITE))

still not working with this solution.
An alternative and unreliable hack would be to just carry on and not
call exit (e.g. delete the line exit(EXIT_FAILURE);).

remove exit(EXIT_FAILURE) will do something the same before and the data
will get messed up.
PostMessage() function returns ERROR_NOT_ENOUGH_QUOTA
Incidentally, rather than piping the command file to pgnuplot (which is
causing problems, since that doesn't seem to be what pgnuplot was
designed for), why not just pass the name of the command file as a
command line parameter to wgnuplot (or pgnuplot)?

wgnuplot.exe can open a file and it works fine.
of course, if we forgid pipe, open a file should never get the problem.

here is the comments from gnuplot developer:

" If wgnuplot could take input from a pipe, pgnuplot wouldn't even exist.
But Microsoft decided against that. GUI apps don't have standard
input/output channels, so no piping. "

in unix, it is very easy to get it done. looks that no solutions for
pipe in windows?

thanks for the help.
 
still not working with this solution.

What does it do? Just freeze for ever?
remove exit(EXIT_FAILURE) will do something the same before and the data
will get messed up.
PostMessage() function returns ERROR_NOT_ENOUGH_QUOTA

That implies that wgnuplot is still busy, and is not removing WM_CHAR
messages from its message queue. That would imply that wgnuplot may be
at fault, rather than pgnuplot, assuming pgnuplot is sending the WM_CHAR
messages to the correct window (which you should check).
wgnuplot.exe can open a file and it works fine.
of course, if we forgid pipe, open a file should never get the problem.

here is the comments from gnuplot developer:

" If wgnuplot could take input from a pipe, pgnuplot wouldn't even exist.
But Microsoft decided against that. GUI apps don't have standard
input/output channels, so no piping. "

GUI apps can use stdin and stdout. e.g.
guiapp.exe < textfile.txt
will give guiapp access to textfile.txt via stdin. To use stdout, it
needs to be redirected. One simple way to redirect it is:
AllocConsole();
freopen ("CONOUT$", "w", stdout);
in unix, it is very easy to get it done. looks that no solutions for
pipe in windows?

If guiapp.exe reads from stdin, it will pick up anything piped to it.

Tom
 
here is the comments from gnuplot developer:
GUI apps can use stdin and stdout. e.g.
guiapp.exe < textfile.txt
will give guiapp access to textfile.txt via stdin. To use stdout, it needs
to be redirected. One simple way to redirect it is:
AllocConsole();
freopen ("CONOUT$", "w", stdout);


If guiapp.exe reads from stdin, it will pick up anything piped to it.

Probably a better alternative, since wgnuplot and pgnuplot source code is
available, would be to use a named pipe to transfer the data between the two
instead of PostMessage, and let wgnuplot treat it in the same way as if it
had been received by WM_CHAR. Or use a named event (the name for eitehr
method should be based on the process ID, to let multiple instances run
simultaneously, in a CGI environment for example), which is set whenever
wgnuplot's message queue is empty. Then pgnuplot could post 400 characters
and wait for the event.
 
Back
Top