🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.nativeapi
23 messages
23 total messages Started by Stefano Bonifazi Sun, 24 Dec 2006 09:58
form inside a dll loaded by a console application
#2792
Author: Stefano Bonifazi
Date: Sun, 24 Dec 2006 09:58
30 lines
1989 bytes
Hi all!
  I know how to create a form inside a dll, and make the module that 
load the dll show it! ...It's quite easy! ... But if I try to load that 
dll and show the form form inside a console application I notice that my 
form does not answer any more to windows messages :(
I tried to create a hidden window by the following code:

__fastcall TNodzSimulatorForm::TNodzSimulatorForm(TComponent* Owner)
         : TForm(Owner)
{
  FWindowHandle = AllocateHWnd(MyWndProc);
}
//---------------------------------------------------------------------------
void __fastcall TNodzSimulatorForm::MyWndProc(TMessage &Msg)
{
  Msg.Result = DefWindowProc(FWindowHandle, Msg.Msg, Msg.WParam, 
Msg.LParam);
}
//------------------------------------------------------------------------------
__fastcall TNodzSimulatorForm::~TNodzSimulatorForm()
{
  DeallocateHWnd(FWindowHandle);
}
//----------------------------------------------------------------------------- 


but nothing is changed :(
Please it's very urgent.. and I don't know what to do!
Thank You very much in advance!
Stefano B.
Re: form inside a dll loaded by a console application
#2793
Author: Remy Lebeau (TeamB)
Date: Mon, 25 Dec 2006 21:05
13 lines
1272 bytes
"Stefano Bonifazi" <stefboombastic@email.it> wrote in message
news:458e4f48@newsgroups.borland.com...

> if I try to load that dll and show the form form inside a console
> application I notice that my form does not answer any more to
> windows messages :(

That is because a console application does not have any message queue of its
own by default.  You have to implement one manually.


Gambit
Re: form inside a dll loaded by a console application
#2795
Author: Stefano Bonifazi
Date: Tue, 26 Dec 2006 22:16
15 lines
1577 bytes
HiMr Lebeau, thank U for Ur reply!

>> if I try to load that dll and show the form form inside a console
>> application I notice that my form does not answer any more to
>> windows messages :(
> 
> That is because a console application does not have any message queue of its
> own by default.  You have to implement one manually.

You mean that I have to create an hidden window with its WndProc 
callback function inside the console application calling the dll? .. And 
then the form will receive messages again fine? that is I have not to 
process VCL message by myself inside that WndProc?
Best regards!
Stefano B.
Re: form inside a dll loaded by a console application
#2796
Author: Remy Lebeau (TeamB)
Date: Wed, 27 Dec 2006 00:49
63 lines
2948 bytes
"Stefano Bonifazi" <stefboombastic@email.it> wrote in message
news:45919f15@newsgroups.borland.com...

> You mean that I have to create an hidden window with its WndProc
> callback function inside the console application calling the dll?

No.  A TForm already has a suitable window for processing messages.  You do
not need a separate hidden window at all.

The real problem is that console applications do no have any message queue
for receiving and dispatching the messages in the first place, so there is
nothing for the TForm to process.  That is what you have to implement
manually in your console code.  The simpliest message queue is one that
calls Peek/GetMessage(), TranslateMessage(), and DispatchMessage()
repeatedly for the lifetime of the process, or at least while the TForm is
active.  For example:

    #include <windows.h>

    BOOL CALLBACK HandlerRoutine(DWORD dwCtrlType)
    {
        PostQuitMessage(0);
        return TRUE;
    }

    int main(int argc, char** argv)
    {
        SetConsoleCtrlHandler(&HandlerRoutine, TRUE);

        // load DLL...
        // show TForm...

        MSG msg;
        while( GetMessage(&msg, NULL, 0, 0) > 0 )
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);

            switch( msg.message )
            {
                case WM_SYSCOMMAND:
                    if( (msg.wParam & 0xFFF0) != SC_CLOSE )
                        break;
                    // fall though to the next block...

                case WM_CLOSE:
                    if( PeekMessage(&msg, NULL, WM_QUIT, WM_QUIT,
PM_NOREMOVE) == 0 )
                        PostQuitMessage(0);
                    break;
            }
        }

        // close TForm...
        // unload DLL...

        SetConsoleCtrlHandler(&HandlerRoutine, FALSE);
        return 0;
    }


Gambit
Re: form inside a dll loaded by a console application
#2797
Author: Stefano Bonifazi
Date: Wed, 27 Dec 2006 19:55
15 lines
1903 bytes
  Hi Mr Lebeau! Thank U for Ur reply, and above all for the full working 
code!
Anyway that is exactly what I wished to avoid! :) ... Well my project is 
  divided in two parts: a console project that is compiled with another 
IDE, not written by me, and my Borland Style VCL forms embedded in the 
DLL... I should minimize the code that launches my forms from inside the 
console application! I cannot modify the main such way.. it already sits 
on its loop doing other than windows messages processing.. I hoped I 
could do all in a separate thread.. I tried creating a TApplication 
inside a thread that then created my forms... it worked, but then the 
application never stopped even if I closed all the forms, or I called 
Terminate!
Hope U have a workaround...
Thank U again for Ur help!
Stefano B
Re: form inside a dll loaded by a console application
#2798
Author: Remy Lebeau (TeamB)
Date: Wed, 27 Dec 2006 20:48
41 lines
2803 bytes
"Stefano Bonifazi" <stefboombastic@email.it> wrote in message
news:4592cf7c$1@newsgroups.borland.com...

>   Hi Mr Lebeau! Thank U for Ur reply, and above all for the full
> working code! Anyway that is exactly what I wished to avoid! :) ...

Then you can't use a TForm (or any other type of window) in a console
application.  A message queue is required in order for messages to work
properly.  A DLL has no way of knowing whether it is being loaded by a GUI
application that has a message queue, or a console application that does
not.

If you want the DLL to run its own queue, then you should export a separate
blocking function from the DLL that console applications call but GUI
applications do not call.  If you don't want to implement the message queue
manually, you could use TForm::ShowModal() to handle it for you.

> I should minimize the code that launches my forms from inside the
> console application!

Then you will have to export a separate function specifically for console
applications to use, and let the function do all of the work internally.

> I cannot modify the main such way.. it already sits on its loop doing
> other than windows messages processing..

If the console application already has an active message queue, then your
TForm should have already been working from the very beginning.

> I hoped I could do all in a separate thread..

VCL windowed components (including TForm) do not work well in worker
threads.  For the most part, the VCL is not thread-safe at all.  If you must
use a window in a thread, then you should use the Win32 API directly
instead.  And there must be a message queue in whatever thread is calling
the DLL.  Messages can be received for a window only in the same thread that
creates the window.


Gambit
Re: form inside a dll loaded by a console application
#2799
Author: Stefano Bonifazi
Date: Wed, 27 Dec 2006 21:14
42 lines
2778 bytes
Thank U Mr. Lebeau!

Remy Lebeau (TeamB) wrote:
> Then you can't use a TForm (or any other type of window) in a console
> application.  A message queue is required in order for messages to work
> properly.  

Well it seems this time I get into something impossible to do :(

> If you want the DLL to run its own queue, then you should export a separate
> blocking function from the DLL that console applications call but GUI
> applications do not call.  If you don't want to implement the message queue
> manually, you could use TForm::ShowModal() to handle it for you.

Impossible the console application should continue its work in spite of 
what my form does ...

> If the console application already has an active message queue, then your
> TForm should have already been working from the very beginning.

No the console application has a loop that does other than processing 
windows messages.. low level stuff with high priority

> VCL windowed components (including TForm) do not work well in worker
> threads.  For the most part, the VCL is not thread-safe at all.  If you must
> use a window in a thread, then you should use the Win32 API directly
> instead.  

If I have to start coding all the windows in WinAPI the wonder of 
borland vanishes and I'd better use the MS VC++

And there must be a message queue in whatever thread is calling
> the DLL.  Messages can be received for a window only in the same thread that
> creates the window.

But if I create a window inside a thread spawned by the DLL, cannot 
those messages be received by the thread provided that window has its 
message queue?


Thank U again...
Stefano B.
Re: form inside a dll loaded by a console application
#2800
Author: Remy Lebeau (TeamB)
Date: Wed, 27 Dec 2006 21:55
39 lines
2644 bytes
"Stefano Bonifazi" <stefboombastic@email.it> wrote in message
news:4592e225@newsgroups.borland.com...

> Well it seems this time I get into something impossible to do :(

Apparently so.

> Impossible the console application should continue its work in spite
> of what my form does ...

Then you are running out of options.

> No the console application has a loop that does other than processing
> windows messages.. low level stuff with high priority

Then that loop will have to handle messages as well.  Or at the very least,
have your DLL export a function to process any pending messages in the
calling thread, and then the console application's loop can call that single
function periodically.

> If I have to start coding all the windows in WinAPI the wonder of
> borland vanishes and I'd better use the MS VC++

When it comes to working with the API directly, VC++ does not gain you
anything that Borland does not already do.  You will still have the same
amount of work in your code, so you may as well stick with the Borland
compiler if that is what you are comfortable with.

> But if I create a window inside a thread spawned by the DLL, cannot
> those messages be received by the thread provided that window has its
> message queue?

Like I said earlier, messages for a window can only be received by the
thread that created the window.  A window is tied to a specific thread.  No
other thread can receive messages for that window.


Gambit
Re: form inside a dll loaded by a console application
#2801
Author: John van de Geyn
Date: Wed, 27 Dec 2006 22:26
37 lines
2364 bytes
Instead of creating a new Form would it not be easier to spawn a new stand 
alone application from the DLL?

John

"Stefano Bonifazi" <stefboombastic@email.it> wrote in message 
news:458e4f48@newsgroups.borland.com...
> Hi all!
>  I know how to create a form inside a dll, and make the module that load 
> the dll show it! ...It's quite easy! ... But if I try to load that dll and 
> show the form form inside a console application I notice that my form does 
> not answer any more to windows messages :(
> I tried to create a hidden window by the following code:
>
> __fastcall TNodzSimulatorForm::TNodzSimulatorForm(TComponent* Owner)
>         : TForm(Owner)
> {
>  FWindowHandle = AllocateHWnd(MyWndProc);
> }
> //---------------------------------------------------------------------------
> void __fastcall TNodzSimulatorForm::MyWndProc(TMessage &Msg)
> {
>  Msg.Result = DefWindowProc(FWindowHandle, Msg.Msg, Msg.WParam, 
> Msg.LParam);
> }
> //------------------------------------------------------------------------------
> __fastcall TNodzSimulatorForm::~TNodzSimulatorForm()
> {
>  DeallocateHWnd(FWindowHandle);
> }
> //-----------------------------------------------------------------------------
>
>
> but nothing is changed :(
> Please it's very urgent.. and I don't know what to do!
> Thank You very much in advance!
> Stefano B. 
Re: form inside a dll loaded by a console application
#2802
Author: Ed Mulroy
Date: Thu, 28 Dec 2006 02:44
13 lines
1750 bytes
FWIW:

I have opened a GUI window in a console mode application.  Unfortunately I 
did it a while ago and it was a Win32 and not VCL application.

As I remember the console seemed to have its own message loop.  I do not 
remember how I handled that and will look around to see if I can out find 
what I did.

.  Ed

> Remy Lebeau wrote in message
> news:4592ebe5$1@newsgroups.borland.com...
Re: form inside a dll loaded by a console application
#2803
Author: Remy Lebeau (TeamB)
Date: Thu, 28 Dec 2006 04:09
17 lines
1843 bytes
"Ed Mulroy" <dont_email_me@bitbuc.ket> wrote in message
news:45932f76@newsgroups.borland.com...

> I have opened a GUI window in a console mode application.

Console applications are still Win32 applications, so they have access to
the Win32 API and can use GUI resources.

> As I remember the console seemed to have its own message loop.

A console does not have a GUI message loop.  There are no windows involved
by default.  A console is a self-contained environment.  That is why I keep
telling Stefano that a message loop has to be explicitally written.


Gambit
Re: form inside a dll loaded by a console application
#2804
Author: Ed Mulroy
Date: Thu, 28 Dec 2006 04:55
11 lines
1666 bytes
> A console does not have a GUI message loop.

The messages are handled somewhere within Windows.  The console window is 
still a window.   You can even get an handle to it and change the caption. 
I don't think you can subclass or superclass the wndproc or somehow get into 
its message loop.

.  Ed

> Remy Lebeau wrote in message
> news:459343d1@newsgroups.borland.com...
Re: form inside a dll loaded by a console application
#2806
Author: Stefano Bonifazi
Date: Thu, 28 Dec 2006 08:53
15 lines
1621 bytes
Hi! Thank You for Ur reply!


John van de Geyn wrote:
> Instead of creating a new Form would it not be easier to spawn a new stand 
> alone application from the DLL?

of course it would! :) ... That is right the way I'm following now, 
leaving in the dll just a TCPIP blocking client that creates a bridge 
between the console application and the visual VCL application!
Of course if the console could launch directly a form in the dll would 
be much better, but it sounds that the price is always that it has to 
sit looping in message processing :(
Thank You for Ur suggestion anyway!
Stefano B.
Re: form inside a dll loaded by a console application
#2805
Author: Stefano Bonifazi
Date: Thu, 28 Dec 2006 08:59
16 lines
1752 bytes
Hi Mr Lebeau!

Remy Lebeau (TeamB) wrote:
> "Stefano Bonifazi" <stefboombastic@email.it> wrote in message
> news:4592e225@newsgroups.borland.com...
> 
>> Well it seems this time I get into something impossible to do :(
> 
> Apparently so.

I have to admit that I've been trying to solve that dilemma since a lot 
of time.. I thought that my low skill was the cause of my failure! 
Thanks Gambit!!

Best regards!
Stefano B.
Re: form inside a dll loaded by a console application
#2807
Author: John van de Geyn
Date: Thu, 28 Dec 2006 09:14
29 lines
2413 bytes
What is it your actualy trying to achieve? Sounds like you have a Console 
application that uses a function in a DLL to I assume needs to get some user 
information. Is this correct?
It might be easier and more reliable to just use a temp file to exchange 
information(using say the HANDLE of the application you spawn as a 
filename). Although I have also used TCPIP succesfully in the past for 
exchanging info between applications. I'm  just wondering when the program 
is used on networked machines with tight security settings that ports might 
not be available.

John

"Stefano Bonifazi" <stefboombastic@email.it> wrote in message 
news:459385ea@newsgroups.borland.com...
> Hi! Thank You for Ur reply!
>
>
> John van de Geyn wrote:
>> Instead of creating a new Form would it not be easier to spawn a new 
>> stand alone application from the DLL?
>
> of course it would! :) ... That is right the way I'm following now, 
> leaving in the dll just a TCPIP blocking client that creates a bridge 
> between the console application and the visual VCL application!
> Of course if the console could launch directly a form in the dll would be 
> much better, but it sounds that the price is always that it has to sit 
> looping in message processing :(
> Thank You for Ur suggestion anyway!
> Stefano B. 
Re: form inside a dll loaded by a console application
#2808
Author: Stefano Bonifazi
Date: Thu, 28 Dec 2006 12:35
30 lines
2121 bytes
Hi!
John van de Geyn wrote:
> What is it your actualy trying to achieve? Sounds like you have a Console 
> application that uses a function in a DLL to I assume needs to get some user 
> information. Is this correct?

well let's say that the exchange of info is supposed to be 
bidirectional! The GUI is supposed to pass user info to the console 
application, and display its informations back to the user!

> It might be easier and more reliable to just use a temp file to exchange 
> information(using say the HANDLE of the application you spawn as a 
> filename). 

Too slow! and rude! :)

Although I have also used TCPIP succesfully in the past for
> exchanging info between applications. I'm  just wondering when the program 
> is used on networked machines with tight security settings that ports might 
> not be available.
> 

Well that will be only a matter for network administrators :) ... and 
this solution will also allow to have a remote GUI communicating with 
the console application!


Thank U!
Regards!
Stefano B.
Re: form inside a dll loaded by a console application
#2809
Author: Ed Mulroy
Date: Thu, 28 Dec 2006 17:05
92 lines
3288 bytes
I cannot find the old app where I played with both a console and GUI windows 
in an app.

However there is a window associated with the console.  You cannot subclass 
it but you can do some things with it.  For example, here's a 'quicky' that 
moves it around.

.  Ed

  -----------------------
  // can be built from the command line with
  // bcc32 -WCR filename

  #include <windows.h>

  class Console
    {
  public:
    Console();
    ~Console() {}
    operator HWND () const { return console_hwnd; }

  private:
    Console(const Console &);
    Console operator = (const Console &);

    HWND console_hwnd;
    static char new_title[];
    }; // end class Console

  char Console::new_title[] = " ZAB}{NEW TITLE][ABC";

  Console::Console()
    {
    char orig_title[1024];

    // make sure the new title is unique
    *new_title = ' ';

    for (char c = '!';
         FindWindow(NULL, new_title) && (c <= '`');
         ++c)
      {
      *new_title = c;
      }

    GetConsoleTitle(orig_title, sizeof(orig_title));

    if (SetConsoleTitle(new_title))
      {
      Sleep(10); // Give Win9x/WinME time to update the title
      console_hwnd = FindWindow(NULL, new_title);
      SetConsoleTitle(orig_title);
      }
    else
      {
      console_hwnd = NULL;
      }
    } // end Console::Console


  void ShowWindowMovement(HWND hwnd)
    {
    RECT rect;

    GetWindowRect(hwnd, &rect);

    int top = rect.top;
    int high = rect.bottom - top;
    int wide = rect.right - rect.left;

    for (int i = 0, x = rect.left - 20;
         i < 4;
         ++i, x += 5)
      {
      MoveWindow(hwnd, x, top, wide, high, TRUE);
      Sleep(1000);
      }
    } // end ShowWindowMovement

  int main()
    {
    Console cons_info;

    ShowWindowMovement(cons_info);
    return 0;
    }

  -----------------------

> Remy Lebeau wrote in message
> news:459343d1@newsgroups.borland.com...
Re: form inside a dll loaded by a console application
#2810
Author: Remy Lebeau (TeamB)
Date: Thu, 28 Dec 2006 18:32
15 lines
1837 bytes
"Ed Mulroy" <dont_email_me@bitbuc.ket> wrote in message
news:4593f94f$1@newsgroups.borland.com...

> However there is a window associated with the console.  You cannot
> subclass it but you can do some things with it.  For example, here's a
> 'quicky' that moves it around.

As far as I know, MoveWindow() does not use the message queue.  It sends the
appropriate window messages directly to the window procedure as if they were
sent with SendMessage().  So of course your example would work without a
queue being present in the console application's code.


Gambit
Re: form inside a dll loaded by a console application
#2813
Author: Bob Gonder
Date: Fri, 29 Dec 2006 16:35
12 lines
1757 bytes
Ed Mulroy wrote:

>I have opened a GUI window in a console mode application.  Unfortunately I 
>did it a while ago and it was a Win32 and not VCL application.

>As I remember the console seemed to have its own message loop.  I do not 
>remember how I handled that and will look around to see if I can out find 
>what I did.

I used DialogBox() which has it's own internal message loop, and
doesn't return until the window closes.
Perhaps you did too.
Re: form inside a dll loaded by a console application
#2814
Author: Ed Mulroy
Date: Fri, 29 Dec 2006 18:01
14 lines
1773 bytes
Possibly but I don't remember for sure and cannot find the program in which 
I did it.

Even if I had, I remain secure in the statement that one can put up a 
functioning non-dialog GUI window in a console app.

.  Ed

> Bob Gonder" <notbg@notmindspring.invalid> wrote in message 
> news:u6gap296dev9r8edn5hu797lescpu2oesf@4ax.com...
>
> I used DialogBox() which has it's own internal message loop,
> and doesn't return until the window closes.
> Perhaps you did too.
Re: form inside a dll loaded by a console application
#2815
Author: Remy Lebeau (TeamB)
Date: Fri, 29 Dec 2006 18:08
14 lines
1904 bytes
"Ed Mulroy" <dont_email_me@bitbuc.ket> wrote in message
news:459557fa@newsgroups.borland.com...

> Even if I had, I remain secure in the statement that one can put
> up a functioning non-dialog GUI window in a console app.

I never said it couldn't be done.  A console app is a Win32 app, so it
has full access to the Win32 API and can create and display its own
GUI windows.  But a console app does not have any message loop by
default.  It must be implemented manually in the user's own code.


Gambit
Re: form inside a dll loaded by a console application
#2816
Author: Ed Mulroy
Date: Fri, 29 Dec 2006 19:54
24 lines
2323 bytes
> I never said it couldn't be done...

Note that my message was a response to what Bob Gonder's message.  It was 
not intended as an argument against what you said.

> ...a console app does not have any message loop by
> default.  It must be implemented manually in the user's
> own code.

Agreed.  A message loop also must be implemented manually in a GUI program 
(other than a dialog-box only one) so that is as expected.

.  Ed

> Remy Lebeau wrote in message
> news:45955986$1@newsgroups.borland.com...
>
>> Even if I had, I remain secure in the statement that one can put
>> up a functioning non-dialog GUI window in a console app.
>
> I never said it couldn't be done.  A console app is a Win32 app, so it
> has full access to the Win32 API and can create and display its own
> GUI windows.  But a console app does not have any message loop by
> default.  It must be implemented manually in the user's own code.
Re: form inside a dll loaded by a console application
#2817
Author: Ed Mulroy
Date: Sat, 30 Dec 2006 03:46
30 lines
2528 bytes
In the attachments group there is a message titled GUI window in console 
app.

It is a not very well written demo of something like we are talking about. 
No dialogs, just a Win32 app using a normal window.  For those like me who 
prefer the command line for small demos, a make file is included.

While throwing this together I found out why you need to use PeekMessage 
instead of GetMessage.  A GetMessage loop demands at least one message after 
showing the window (even a mouse move will do it).  Peekmessage does not.

It also demos using a shared variable as a flag with which the console can 
cause the thread to end.

.  Ed

> Bob Gonder wrote in message
> news:u6gap296dev9r8edn5hu797lescpu2oesf@4ax.com...
>
>>I have opened a GUI window in a console mode application.
>>Unfortunately I did it a while ago and it was a Win32 and not
>> VCL application.
>
>>As I remember the console seemed to have its own message
>>loop.  I do not remember how I handled that and will look
>>around to see if I can out find what I did.
>
> I used DialogBox() which has it's own internal message loop,
> and doesn't return until the window closes.
> Perhaps you did too.
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads