[ann] WIN32GUI - v1.5.1 released

D

Dilip

(e-mail address removed) (John Torjo) wrote in message > And by the way, could you please point me to how .net + threading +
GUI interact?
Since it seems to me that they interact kind of badly...

On my small C# project I made, it seems that if I do something like

static void other_thread1() {
g_form.txt.Text = "other thread -1";
}


and, make sure I catch the text_changed event:

private void changed_txt(object sender, System.EventArgs e)
{
int i = 0;
}

I catch this in the context of the other thread, as opposed to the
main thread (which is what I would expect). Thus, I need to make my
whole class thread-safe, just because I want to manipulate one of its
controls from another thread.

This strikes me as very bad, compared to Win32 programming, where all
messages are sent on the context of the thread that created the
control, not on the context of the caller.

This is probably OT.

I still don't understand completely what you are doing by seeing your
sample program but as far as .NET is concerned you cannot access any
UI element from a method executing in a non-UI thread. The correct
way to do it is to check if a thread-switch is required and if yes,
the call needs to be marshalled to the UI thread. Like so:

private delegate void MethodExecDelegate(string somevalue);

private void method_executing_on_non_ui_thread(string somevaluetoset)
{
if (this.InvokeRequired)
this.BeginInvoke(
new MethodExecDelegate(method_executing_on_non_ui_thread),
null);
else
some_ui_control.Text = somevaluetoset;
}

The above method is part of a class derived from System.Windows.Form.

This has been true since the days Windows threading support. As Glen
Low points out in another post, worker threads need to use the
PostMessage API to update controls created by the UI thread. Also
using SendMessage API will cause a blocking call -- therefore if the
UI is busy for some reason and can't handle the call right away, the
worker thread will be needlessly blocking.

thanks
--Dilip
 
I

Ioannis Vranos

John said:
That was not the point. The point is: the context in which you catch
notifications (that is, in the thread that created the window, or in
the thread they occur?)

In other words:
I'm in another thread, and do this:

g_form.txt.Text = "other thread -1";

I would expect to catch the text_changed notification in the main
thread (the thread that created g_form).

Best,
John


I do not think that this should be the desirable, since the main thread
may terminate before the other threads.

At least this is the case in .NET world.
 
J

John Torjo

Seanairt said:
How can it possibly "deprecate" the standard? Further, wouldn't that mean

That's not what I meant.
You'll be writing C++/CLI. Which are some extensions targetted
specifically at CLR. It is my (gut) feeling that this simply won't be
C++ as we know it (at least when dealing with GUI)...

You'll be tempted to use more and more services of CLR (example:
Console::WriteLine), which will make your code not portable.

I hope I'm wrong though.

Best,
John


John Torjo, Contributing editor, C/C++ Users Journal
-- "Win32 GUI Generics" -- generics & GUI do mix, after all
-- http://www.torjo.com/win32gui/
-- v1.5 - tooltips at your fingertips (work for menus too!)
+ bitmap buttons, tab dialogs, hyper links, lite html
 
N

Nebi

I do not want to stop your effort, however doesn't .NET already do the
same things?


Also keep in mind that the Longhorn API will be WinFX (.NET), replacing
Win32.

Win32 will not be developed any more and will remain for compatibility
purposes, the same way Win16 is today.

I'm .Net beginer

TC++PL Page 9.

1.3.2 Philosophical Note

<quote>

A programming language serves two related purposes: it provides a
vehicle for the programmer to specify actions to be executed, and it
provides a set of concepts for programmer to use when thinking about
what can be done. The first purpouse ideally requiers a language that is
"close to mashine" ...

</quote>

1.) Can you explain me with JITCompliler what is close to mashine?

2.) Can I choose a vendor for JITCompiler?

IMO having .Net as one of the options is good, but being forced to it by
not supporting Win32 API-s is not.
 
I

Ioannis Vranos

John said:
That's not what I meant.
You'll be writing C++/CLI. Which are some extensions targetted
specifically at CLR. It is my (gut) feeling that this simply won't be
C++ as we know it (at least when dealing with GUI)...

You'll be tempted to use more and more services of CLR (example:
Console::WriteLine), which will make your code not portable.

I hope I'm wrong though.


Actually when having to do with system-dependent code like GUI or
networking etc, you can't expect much portability.


On the other hand, in real CLI applications Console::WriteLine() is the
facility least used in reality. :)


In any case, System::Console is part of the CLI library so it is both
source and binary portable to all CLI VMs. If you want source code
portability to non-CLI VMs too, you can use std::cout.


In any case, it is always up to you to use as much as ISO C++ as
possible. For example, myself use std::string in .NET code as much as
possible, instead of CLI System::String etc.


This has always been the case.
 
J

John Torjo

Besides, I'd really like it if I could do CLI/C++ coding for Avalon -
"Avalon" (a subset of WinFX) will be equally accessible from all .NET
languages, especially C++/CLI, so I do not know what you mean exactly
with the above.

I was wrong.
For now, you need the PDC release of Visual Studio Whidbey, which I
donot (yet) have.

Best,
John


John Torjo, Contributing editor, C/C++ Users Journal
-- "Win32 GUI Generics" -- generics & GUI do mix, after all
-- http://www.torjo.com/win32gui/
-- v1.5 - tooltips at your fingertips (work for menus too!)
+ bitmap buttons, tab dialogs, hyper links, lite html
 
J

John Torjo

Seanairt said:
How can it possibly "deprecate" the standard? Further, wouldn't that mean

However, seeing the progress done by C++/CLI, and the fact that Herb
is in charge of C++/CLI, makes me change my mind. Thus, I apologize
for that statement.

It seems the future is bright, after all ;)

Best,
John


John Torjo, Contributing editor, C/C++ Users Journal
-- "Win32 GUI Generics" -- generics & GUI do mix, after all
-- http://www.torjo.com/win32gui/
-- v1.5 - tooltips at your fingertips (work for menus too!)
+ bitmap buttons, tab dialogs, hyper links, lite html
 
J

John Torjo

Admittedly the syntax is clunky, especially for simple methods. But if
your method needs to do a lot of work the syntactic overhead is not
much, since you would have to do the equivalent with PostMessage and
packing and unpacking the arguments yourself.

needlessly complex, if you ask me.
Yes you can, but this hides the latency behind the SendMessage. When

Not if you're aware of it.
your other thread calls SendMessage, it blocks as the GUI does its
work, and also waits for the function return. In a typical threaded
Yes.

design, you want the other thread to continue to do work while the GUI
updates e.g. if the other thread is reading a giant file from the
network or busy rendering something.

so? (see below)
Excessive use of SendMessage then
causes both threads to be serialized, and you might as well just use
one thread instead of two.

Usually you seldom need to do a GUI update from a non-GUI thread.
You'll most likely need it for small things - like, update the text of
a label, update a progress bar, etc. - that sort of thing.

In this case, use of SendMessage simplifies things (for one thing, in
case you want to PostMessage and one of the params is a string, you
have to later take care of releasing it - this issues do not occur
with SendMessage).

At the current processor speeds, for small things, I prefer
SendMessage (also, if you look at the docs for win32gui - you don't
use SendMessage directly - there are wrappers over it).
Therefore, a lot of developers who use Win32 strictly seperate GUI and
non-GUI functionality in their threads. Then if the non-GUI thread
needs to get the GUI to do something, they define a custom message on
the GUI thread that does all of what they want, then they PostMessage

If you prefer, you can do this as well - but do it only if you know
you need it.

And besides, you should take a look at win32gui - it completely
separates (the) event handling (thread), from the window class itself:
http://www.torjo.com/win32gui/doc/event_handling.html

Thus, in your window class, you can implement thread-safety (if
needed), as you wish.

Best,
John


John Torjo, Contributing editor, C/C++ Users Journal
-- "Win32 GUI Generics" -- generics & GUI do mix, after all
-- http://www.torjo.com/win32gui/
-- v1.5 - tooltips at your fingertips (work for menus too!)
+ bitmap buttons, tab dialogs, hyper links, lite html
 
J

John Torjo

I still don't understand completely what you are doing by seeing your
sample program but as far as .NET is concerned you cannot access any
UI element from a method executing in a non-UI thread. The correct
way to do it is to check if a thread-switch is required and if yes,
the call needs to be marshalled to the UI thread. Like so:
[snip]

error prone, if you ask me. But if you're ok with it, sure thing...
This has been true since the days Windows threading support. As Glen

what has been true?
Low points out in another post, worker threads need to use the

they "don't need". It's optional.
PostMessage API to update controls created by the UI thread. Also
using SendMessage API will cause a blocking call -- therefore if the
UI is busy for some reason and can't handle the call right away, the
worker thread will be needlessly blocking.

see my other post (to Glen).

Best,
John


John Torjo, Contributing editor, C/C++ Users Journal
-- "Win32 GUI Generics" -- generics & GUI do mix, after all
-- http://www.torjo.com/win32gui/
-- v1.5 - tooltips at your fingertips (work for menus too!)
+ bitmap buttons, tab dialogs, hyper links, lite html
 
I

Ioannis Vranos

John said:
I was wrong.
For now, you need the PDC release of Visual Studio Whidbey, which I
donot (yet) have.


You can download the Visual C++ Express 2005 Beta 1 for free from:

http://lab.msdn.microsoft.com/express/visualc/default.aspx

[Download the off line files and not the Internet installation, because
it didn't work for me].



and the latest "Visual C++ 2005 Tools Refresh" update for this from:

http://www.microsoft.com/downloads/...f1-9d16-439a-9a5e-e13eb0341923&displaylang=en



Do not download the "October 2004 Community Technical Preview Release"
instead of Beta 1, because in my system the GUI crashes continuously,
and can't create even a simple project.


In few words download the off-line files of "Visual C++ Express 2005
Beta 1" + the latest "Visual C++ 2005 Tools Refresh" and you can work
with C++/CLI.


The latest C++/CLI *draft* standard is:

http://www.plumhall.com/C++-CLI draft 1.7.pdf
 
I

Ioannis Vranos

Dilip said:
This is probably OT.

I still don't understand completely what you are doing by seeing your
sample program but as far as .NET is concerned you cannot access any
UI element from a method executing in a non-UI thread. The correct
way to do it is to check if a thread-switch is required and if yes,
the call needs to be marshalled to the UI thread. Like so:



What do you mean? Consider the code:

Form1.h

#pragma once


namespace test
{
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Threading;


public __gc class Form1 : public System::Windows::Forms::Form
{
public:

// ...

public: System::Windows::Forms::TextBox * textBox1;

// ...
};
}




Form1.cpp


#include "stdafx.h"
#include "Form1.h"
#include <windows.h>

using namespace test;

__gc class SomeClass
{
Form1 *pForm;
public:
SomeClass(Form1 *form): pForm(form) {}

void ModifyText()
{
Thread::Sleep(5000);

pForm->textBox1->Text="Modified text";
}
};



int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
System::Threading::Thread::CurrentThread->ApartmentState =
System::Threading::ApartmentState::MTA;

Form1 *pForm= __gc new Form1;

SomeClass *pSomeClass= __gc new SomeClass(pForm);


Thread *thread1= __gc new Thread(new ThreadStart(pSomeClass,
&SomeClass::ModifyText));

thread1->Name="Thread1";

thread1->Start();

Application::Run(pForm);

return 0;
}



The Form1 class above contains a public TextBox member (for speed, to
avoid implementing access methods or properties).


The SomeClass class whose objects is used by a separate thread, provides
a public method that modifies the TextBox of the form after 5 seconds.
 
D

Dilip

Ioannis Vranos said:
What do you mean? Consider the code:

__gc class SomeClass
{
Form1 *pForm;
public:
SomeClass(Form1 *form): pForm(form) {}

void ModifyText()
{
Thread::Sleep(5000);

pForm->textBox1->Text="Modified text";
}
};

[snipped]

That should be: (Let me give the code in C# -- it should be easily
applicable to MC++)

void ModifyText()
{
if (Form_Reference.InvokeRequired)
Form_Reference.BeginInvoke(new MethodInvoker(ModifyText), null);
else
Form_Reference.TextBox1.Text = "Modified Text";
}

Basically from a non-UI thread its _verboten_ to make any kind of
access to UI elements. Violating this may work as long as you don't
demo this to your CEO :)

Also all property changes don't necessarily translate into a
corresponding windows message (WM_*). In that case its no different
from serializing access to a shared member variable that can be
trampled upon by multiple threads.
 
I

Ioannis Vranos

Dilip said:
[snipped]

That should be: (Let me give the code in C# -- it should be easily
applicable to MC++)

void ModifyText()
{
if (Form_Reference.InvokeRequired)
Form_Reference.BeginInvoke(new MethodInvoker(ModifyText), null);
else
Form_Reference.TextBox1.Text = "Modified Text";
}

Basically from a non-UI thread its _verboten_ to make any kind of
access to UI elements. Violating this may work as long as you don't
demo this to your CEO :)

Also all property changes don't necessarily translate into a
corresponding windows message (WM_*). In that case its no different
from serializing access to a shared member variable that can be
trampled upon by multiple threads.



This multithreading stuff are out of my knowledge, however why this call
of BeginInvoke() is better than what I provided? In a real world
situation I would also place calls to Monitor::Enter(); and
Monitor::Exit() to get and release the lock each time on the TextBox object.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top