Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ Widgets - General questions or Mixed problems » Having my HWND and eating it, too...
Having my HWND and eating it, too... [message #12095] Wed, 10 October 2007 21:29 Go to next message
tvanriper is currently offline  tvanriper
Messages: 85
Registered: September 2007
Location: Germantown, MD, USA
Member
I have a problem.

I'm not using an OCX control. I'm not using OLE or COM in any form for this. I have a function to a third-party library that takes a HWND as its argument.

The HWND needs to represent an area within a TopWindow to which the third-party library may render whatever it wants.

I created a custom class derived from Ctrl, but quickly discovered that Ctrl objects do not have their own HWNDs.

So, I tried creating deriving the class from TopWindow instead, after noticing all the happy fun function for creating HWNDs there. However, for some reason, when I call GetHWND() against this control, I still get a null.

So I'm stumped. At the moment, I am not sure how I should create this window. I've tried some other things, but they lead to assertions.

Does anyone have anything to suggest?
Re: Having my HWND and eating it, too... [message #12097 is a reply to message #12095] Wed, 10 October 2007 21:56 Go to previous messageGo to next message
Oblivion is currently offline  Oblivion
Messages: 1091
Registered: August 2007
Senior Contributor
From where do you get a handle to your window?
If it is your applications main window, (if you are using e.g. mainwindow.run()) you shouldn't try to get a handle to your window in class constructor (unless you explicitly call Open() or OpenMain() -- which, in this case (if you already call run() in your apps main()) you shouldn't use).

You could use instead something safer:

HWND MainWindow::GetHandle()
{
return GetHWND(); // use IsOpen() to check before calling;
}

or

HWND MainWindow::GetHandle()
{
return IsOpen() ? GetHWND() : null; // handle null as an error;
}

and call whenever it's needed.


[Updated on: Wed, 10 October 2007 22:14]

Report message to a moderator

Re: Having my HWND and eating it, too... [message #12098 is a reply to message #12095] Wed, 10 October 2007 22:09 Go to previous messageGo to next message
tvanriper is currently offline  tvanriper
Messages: 85
Registered: September 2007
Location: Germantown, MD, USA
Member
I'm not attempting to do this from within the constructor.

Let me see if I can describe the sequence of events...

1. Application starts.

2. Main window comes up. This one holds all the other windows for the entire application. By 'comes up', I mean that the user is able to see it, play with the knobs, fiddle with the switches, and perhaps give us some money in appreciation.

3. User logs in.

4. Some information flows from the other side of the network to this application, bearing some initialization information for my third-party control.

5. At this point, I want to get an HWND to a window within the main window (a control, if you will) to feed to my third-party functions.

Problem is, when I call GetHWND() on my control, I get '0', because I don't seem to actually have an HWND in my control. I can't give it the HWND for the main application window, because then my third-party function will write over the entire application, rather than the small area I want it to have.
Re: Having my HWND and eating it, too... [message #12099 is a reply to message #12098] Wed, 10 October 2007 22:31 Go to previous messageGo to next message
Oblivion is currently offline  Oblivion
Messages: 1091
Registered: August 2007
Senior Contributor
Ah, I see. I'm converting my MFC-based multiprotocol (so a client-server system is used) messenger to UPP and encountered similar problems.

Well, AFAIK it is not possible that way. If I understand it right, you derive your child windows from TopWindow, but you do not Open() them. Unless they are opened, they cannot be TopWindows; they stay as ctrl (which -- conceptually -- has no HWND). On the other hand, if they are Opened() they cannot be child ctrls anymore, at most they can be child top or popup windows. If your client programs are in U++ too, you could pass ctrl* instead. But if they are not, and you are trying to "draw" something, you could pass a "Rect" and an ID to the ctrl (this means that you have to modify your apps IPC message framework.

Namely, as far as I know there is no HWND of ctrls "in the main window." (AFAIK, not explicitly). Sad



[Updated on: Wed, 10 October 2007 22:43]

Report message to a moderator

Re: Having my HWND and eating it, too... [message #12100 is a reply to message #12095] Wed, 10 October 2007 22:45 Go to previous messageGo to next message
tvanriper is currently offline  tvanriper
Messages: 85
Registered: September 2007
Location: Germantown, MD, USA
Member
I see a hint towards a solution, but I'm not there yet.

If you create a simple application with a WithDropChoice-type control, and set a breakpoint at Ctrl::Create (within Win32Wnd.cpp, which is in CtrlCore), you'll find that a window is created when you expand the drop choice.

Looking further in the code, it seems someone created a Ctrl class object and called its 'PopUp' function, which eventually calls a 'PopUpHWND' function, which itself executes (successfully) a Create().

I want to understand how this window is removed before I go too much further down this line.

I totally understand why U++ doesn't create a lot of windows (and, actually, I really applaud that), but I wish it were easier to create a sub-window. Or, perhaps it is easy, but I just don't see it yet.
Re: Having my HWND and eating it, too... [message #12101 is a reply to message #12100] Wed, 10 October 2007 22:50 Go to previous messageGo to next message
Oblivion is currently offline  Oblivion
Messages: 1091
Registered: August 2007
Senior Contributor
Be careful...

That is a "Popupwindow" of dropchoice -- which exacly works in native U++ way. It is NOT the dropchoice ctrl (as a whole) and not all ctrl's have or are popups (as menus, dropchoices are).

In fact, you can popup any Ctrl by calling Ctrl::Popup().

But, if I understand you right, that will give you a "floating" popup window (such as popup menus); nothing more. Sad


[Updated on: Wed, 10 October 2007 22:55]

Report message to a moderator

Re: Having my HWND and eating it, too... [message #12102 is a reply to message #12095] Wed, 10 October 2007 23:06 Go to previous messageGo to next message
tvanriper is currently offline  tvanriper
Messages: 85
Registered: September 2007
Location: Germantown, MD, USA
Member
I understand that... but it was exactly the clue I needed to fix my problem.

It's a little gnarly, but my control now works mostly the way I want it to work (I need to fix a small problem related to positioning, but it's close).

I needed to create a new control derived from Upp::Ctrl. This control has a constructor (for no real reason, I could probably have ommitted this), and an 'Initialize' function that takes an HWND (the 'owner' HWND) and a Rect (the size of the window to create).

Initialize then calls Upp::Ctrl::Create( HWND owner, WS_CHILD | WS_VISIBLE, 0, false, SW_SHOW, true ) to create the HWND.

I then added a member variable of this class in my control.

When I need to initialize the HWND, I call my new class's Initialize() function, which creates the necessary HWND of exactly the type I needed.

I'm able to feed this HWND into the functions I'm using, and it's painting to the area (except for being slightly above it... something I'm trying to fix now).

All-in-all, it works, but not quite as elegantly as I had hoped. It's still sufficiently U++-like (I think) to be acceptable.
Re: Having my HWND and eating it, too... [message #12103 is a reply to message #12095] Wed, 10 October 2007 23:07 Go to previous messageGo to next message
tvanriper is currently offline  tvanriper
Messages: 85
Registered: September 2007
Location: Germantown, MD, USA
Member
(maybe, if I can think to do this, I'll create some example code to illustrate this solution a little better).
Re: Having my HWND and eating it, too... [message #12104 is a reply to message #12102] Wed, 10 October 2007 23:11 Go to previous messageGo to next message
Oblivion is currently offline  Oblivion
Messages: 1091
Registered: August 2007
Senior Contributor
Sounds like a nice trick, indeed! Smile



icon3.gif  Re: Having my HWND and eating it, too... [message #12116 is a reply to message #12095] Thu, 11 October 2007 19:07 Go to previous messageGo to next message
tvanriper is currently offline  tvanriper
Messages: 85
Registered: September 2007
Location: Germantown, MD, USA
Member
Well, some example code for the trick I used...

Here's the child that creates the HWND...
class ChildCtrl : public Upp::Ctrl
{
public:
	ChildCtrl() : Upp::Ctrl() {};
	void Initialize( HWND owner, const Upp::Ctrl& ctrl )
	{
		SetRect( ctrl.GetRect() );
		Create( owner, WS_CHILD | WS_VISIBLE, 0, false, SW_SHOW, true );
	};
};


Of course, you might need to change the styles to suite your own needs. This is, obviously, Windows-centric stuff, but if you had a need to do something like this for X11, I'm pretty sure you could use a similar technique.

Later, I make use of this within my other control as such:

class TestCtrl : public Upp::Ctrl
{
protected:
	
	ChildCtrl m_wnd;
public:
	TestCtrl()
	{
	};
	
	~TestCtrl()
	{
	};
	
	void IncomingMessage( const SomeCommand& command )
	{
		if ( m_wnd.GetHWND() == 0 )
		{
			m_wnd.Initialize( ::GetActiveWindow(), *this );
		}
		::DoSomeCommand( m_wnd.GetHWND(), command );
	};
	
	void EnableCtrl( bool enable = true )
	{
		if ( enable )
		{
			m_wnd.Show();
		}
		else
		{
			m_wnd.Hide();
		}
	};
};


The only thing not quite working the way I want is the size of window... the HWND seems to think it should appear above where you actually place TestCtrl.

I'm currently working around this by moving the control down well below where I really want it... but I want to fix this when I have some time. It's puzzling the SetRect() seems to be a little inaccurate for HWNDs. I'm guessing that U++ is compensating for something (I will have to dig in the code sometime to see).

Of course, it's also possible that ::DoSomeCommand() is actually putting the video off somewhere, but I kind of doubt it; we use ::DoSomeCommand() elsewhere, and it works just fine.

Using this technique, the control should get deallocated on destruction (our favorite U++ and C++ idiom, from what I've seen). The only awkward thing is that EnableCtrl() bit... I'm having to use this to hide and show the window when necessary. I could probably handle this more elegantly by overriding the Hide/Show commands in TestCtrl() to also hide and show the child control.
Re: Having my HWND and eating it, too... [message #12126 is a reply to message #12116] Fri, 12 October 2007 00:09 Go to previous message
mirek is currently offline  mirek
Messages: 13975
Registered: November 2005
Ultimate Member
Please look at DHCtrl (and perhaps GlCtrl that uses it).

DHCtrl is a special "hack" kind of child widget with HWND (

Mirek
Previous Topic: Toolbar clears after ESC key [solved, it`s the bug in user code]
Next Topic: label text not wrapped
Goto Forum:
  


Current Time: Fri Mar 29 08:59:08 CET 2024

Total time taken to generate the page: 0.01900 seconds