I am working on a project that totally does not want to use the built-in window/dock state and position saving of MFC. This means that in my main frame, I set EnableLoadDockState(FALSE). As much as I love to change it back to TRUE, I can't.
I plan on getting the position where a CDockablePane was docked through onAfterDock() of my CDockablePane. My problem is I have no idea on how to get whether it was placed on the side, top or bottom, on another CDockablePane.
Is there a way to get this information?
Thanks!
I think there is a way to get it, but it's not going to be easy or pretty.
A you're trapping the OnAfterDock, I guess you're not interested in floating panes. So, for docked panes, you can use CDockablePane::GetDefaultPaneDivider (MSDN here), which returns - as MSDN says:
A valid CPaneDivider object if the dockable pane is docked to the main frame window, or NULL if the dockable pane is not docked or if it is floating.
The CPaneDivider object (MSDN here)
...divides two panes, divides two groups of panes, or separates a group of panes from the client area of the main frame window
The following partial screenshot says more:
So, for a regular pane divider, you can use the methods available on CPaneDivider to find the other pane, or another embedded CPaneDivider (so recursive interrogation necessary here) and check if the divider is horizontal or vertical etc.
For the other case described above, look at the CPaneContainerManager class, which (again as MSDN says)
...manages the storage and display of the current docking layout
From here, you can again drill down through the whole docking hierarchy that starts from your original docked pane.
If I were you, I would really really look again at using EnableLoadDockState or at least browse the MFC source code to see if there are any internal helper classes/functions that you can reuse.
I've just solved this issue. I can check CDockablePane's dwStyle (GetPaneStyle()) for CBRS_ALIGN_LEFT, CBRS_ALIGN_RIGHT, etc. No complex methods. Simple.
Related
I have a bit of an issue that involves a CMFCPropertyGridCtrl.
Normally you assign a window size to it and if it cannot fit it sets up a vertical scroll bar (for all I can see this is just the normal generic CWnd associated scrollbar). And this is great for when you just want to dump the control inside a re-sizeable window.
However, I have the reverse situation, where I would like to fit my outer window so that it shows the entire height of the control (such that no scroll bar needs to be created). In order to do that I somehow needs to get an ideal height given the contents of the control. Is that possible in some generic way or just for CMFCPropertyGridCtrl ?
To give a little more background, I have multiple gridctrl's on top of each other so to speak. Therefore, I have put a scrollbar on the outer window so you could say they share that scrollbar (and this one is working just fine). I could go into details why I want this design(as opposed to just one gridctrl with everything), but basicly it's a kind of cards where each card/element has it's own set of properties.
I want to make my own scrollbars for a custom drawn plot, like this image, what would be the best way to go?
Scrollbars should:
Only be visible when mouse hover over it (with fade in/out)
Be a part of the x/y axis of the plot, like in the picture
Not have any arrow buttons, just the thumb Thinner than the normal scrollbars
Would you suggest to:
Create everything from scratch, handling paging, scrollwheel etc.
Try to inherit CScrollBar and do my own drawing?
From what I've read, it's not very easy to customize scrollbars in MFC, for example here)
First off, these have to be scrollbar (or other) controls, not window scrollbars (used for scrolling a window).
Second, the statement "it's not very easy to customize scrollbars in MFC", is only partially true. MFC is a "thin wrapper" of Windows API, so you should better refer to the documentation of the Windows scrollbar control.
Then there is the CScrollBar class, but took a short look, and indeed, it does not really offer anything more than the Windows scrollbar does. As for the sample in the link you posted is a new (custom) control (painting everything on its own), i.e. literally "from scratch", not inheriting anything from CScrollBar.
So, you have to look into the Windows scrollbar control, and what it offers. Did take a look, and saw few things. Unfortunately there seems to be no owner-draw functionality. You can process the WM_CTLCOLORSCROLLBAR message, but this only allows you to change colors.
And according to the documentation the background color only. This appears to be the only possible customization, apart from the SBM_ENABLE_ARROWS message, which can hide the arrows. And no fading effect. If these are enough to you, you could try the Windows/MFC scrollbar, otherwise try writing your own.
I wanted to develop a widget container (still on python 2.7 and gtk2), which would be placed in a scrolled window, and could be freely moved and resized in the window, such that: click & drag within the widget would move it inside the window; and when widget's corners / edges are visible in the window, it would expose drag handles for resizing - otherwise, if it is bigger than the window area, it would scale up and down (zoom in and out) on middle-click.
Of course, I want to keep the amount of custom coding of this widget to a minimum, so I though looking into what's available in gtk2 first. It turns out, the only element exposing resize drag handles is gtk.Window - and at that, only if it is a main (or root) window; otherwise, if a window is placed inside a widget, its size is apparently set by the widget, and so there are no drag handles (not menus, titlebars etc). I was wandering why this is - and it seems it is due to multiple document interface (MDI) being considered evil by gtk developers, see e.g. Re: [gtk-list] Resizing widgets with a mouse or Does GTK support MDI? - Linux/BSD whirlpool.net.au.
Just to demonstrate the behavior that I want, I used a PyQt4 code from Python PyQt/PySide QMdiArea subwindows scroll not working in TabbedView - Stack Overflow, since as it turns out, Qt does have an MDI area. So here's the gist of it - if a corner is visible, a resize drag handle appears, and resize drag action can be started:
When you thus drag the corner outside of the window - the scrollbars automatically indicate the new size/position of the inner widget (note the window got also moved a bit in this screenshot below, that was manual and unintended):
Again, I don't really need a window (as in titlebars, menus) - just a widget container that would behave in this way, so I could put e.g. a table (e.g. TreeView) or an image in it, as the situation demands - and at least not worry about recalculating the "outer" scrollbars (naturally, I'd expect I'd have to code the rest of my custom behavior myself). Also, I just need a single widget placed in a window like that for now (so no "multiple document"s).
While Qt seems to offer this in a way, I don't have the possibility right now to get into it to the level of doing something like this; and the same goes for WxWindows (see e.g. wxPython-users - How to resize Widgets? - possible, but as there is no code there, I cannot see if geometry calculation coding is required or not).
So I was wondering - is there a widget I may have missed, that would implement the above behavior, and that I could take as a base for customization? If not, what options do I have to implement something like the above on gtk2 (eventually with Python)?
I'm not sure this would work, but I suggest looking into GtkOffscreenWindow; put the inner widget into that, and render it to a GtkDrawingArea inside a GtkScrolledWindow. This would probably make the scrollbars behave properly depending on the size of the drawing area.
What you won't get:
window titlebars, you'll have to render those yourself because GTK doesn't know about them, they're part of the window manager. (Note, the inner window in the Qt example has a different titlebar than the outer window - I suspect this is the same thing.)
drag handles to resize the window, you'll have to code those yourself, as you expected.
You might also want to look at how the Glade GUI designer does this.
My application has a big graphics area with some controls (sliders, buttons, text edit controls) in a side panel. The graphics area understands some keyboard commands.
My problem is that when a control in the side panel is in focus, the main graphics area won't receive any keyboard commands, so this confuses the users. However, for some controls, this is intended, e.g. text edit controls.
What I want is the focus to automatically return to the graphics area at the earliest possible occasion (which I call "greedy" focus) -- e.g. when text editing is finished (Enter key), or when the user has selected an item from a combo box.
I am looking for a clean and robust strategy for dealing with the problem, either using Windows API or Borland Vcl.
I'd appreciate if you want to share your ideas.
I haven't fully solved the problem yet, but a very useful message to intercept on form level is CM_DIALOGKEY (Borland Vcl only). It gets sent for every key that is normally used for navigating within the UI. That is, cursor keys, tab and shift-tab, Enter and possibly others.
I've added an event handler for CM_DIALOGKEY that returns the focus to the graphics area and also forwards the key press to that component. This way the user can still control the UI elements via keyboard (important for text entry), but cursor keys are handled by the graphics area.
I know what you mean I had similar problem with some BIG apps lice CAD/CAM ...
My solution is simple, robust and I use it for years.
1.all keystrokes handling for that gfx area
must be done in events of the Form where the area is located
not in panels,paint box whatever...
2.create unfocus function (preferably member of form but it is not required)
this function will loose focus of any VCL item
so the focus goes to form itself which is what you want
I am using this:
//---------------------------------------------------------------------------
void main_unfocus()
{
Main->bt_unfocus->Visible=true;
Main->bt_unfocus->SetFocus();
Main->bt_unfocus->Visible=false;
}
//---------------------------------------------------------------------------
Main is the Form pointer
bt_unfocus is button (can be any focusable VCL component)
I place this button usually on the left upper corner of App and set its size to 2x2 pixels
it is invisible at start
the idea is to set focus to it (but first unhide it so no exception is thrown)
and then hide it so it loses focus
work well in BCB5 and BDS2006 (did not used it with any other IDE)
as you can see most of the time is this component invisible
4.now when to call main_unfocus ?
when you go with mouse from outside to inside of your gfx area (OnMouseMove event)
or when you click on it
also you can combine this with remembering if the focus is or not in gfx area
that can be done with events like OnExit ...
or when you hit Esc while focus is inside edit box ...\
I am sure you grasp the idea and adjust this to your needs
Hope it helps
I have a CDHTMLDialog in a BHO that I want to be partially transparent, in the sense that the transparent area changes according to the logic of the dialog. I got it to become transparent visually (using SetLayeredWindowAttributes), but it is critical to make this region truly transparent, because otherwise when I click on the transparent region my clicks do not reach the IE window which is below the transparent part of my dialog. I temporarily fix this by constantly resizing my dialog according to the size of the active part of the dialog, but I can't keep up with this forever...
I think the solution has something to do with what windows calls "regions" (http://msdn.microsoft.com/en-us/library/dd162915%28VS.85%29.aspx) but I'm not exactly sure how to work with them. Can anyone point me in the right direction?
I don't think you want to make parts of your window transparent, what you want to do is (I think) set the window region (like you mention). Read the MSDN on SetWindowRgn() - basically you define a GDI object of type HRGN (if you're using MFC, CRgn) which described a surface of a certain shape, and eventually with parts cut out. Windows then considers only the 'region' that you set on a window as the part of the window to use. Basically it's how you make non-rectangular windows. A 'region' isn't a 'transparent' part of a window, it's a way to discard areas of a window, in a way.
I found the way to make an entire window transparent and click-through here:
http://www.codeproject.com/KB/wtl/transparent.aspx
But it's not useful for my case where I only want the transparent part of my window (transparent by HTML/CSS definitions) to be click-through...
Update: Apparently, the clicks are supposed to go through the transparent parts (see http://jalaj.net/2007/02/05/form-with-a-hole/), but in my CDHTMLDialog they don't. My best guess is that a sub-window of the BHO catches my clicks, but I don't really think that makes much sense...