UI layout nightmare with WinAPI - winapi

I would like to know what should I do with GUI layout under WinAPI/MFC.
In the ideal world I should just create the form/dialog via resource editor, and everything should just work. In the real world the dialog editor is ancient behemoth from the ice-age and doesn't support most of the comctl32 controls.
This is where the problem creeps up. Dialog editor uses DLU units, and when I create new controls at runtime, I have to express them in pixel offsets.
I stumbled upon one article about calculating DLUs based on font http://support.microsoft.com/kb/145994/en-us, but also saw a warning somewhere that dialogs can have non system fonts in some circumstances, so this approach is not very safe. Plus the article seems to look only at English characters, without regard to all other characters in unicode space which might be wider?.
Has anyone done a research in this direction and found a better way?
P.S.: No Winforms/WPF/Delphi, requirements.

the dialog editor is ancient behemoth from the ice-age and doesn't support most of the comctl32 controls
It doesn't need to support the controls directly, you can still use it just for positioning by inserting it as a custom control and filling in the window class in the property page. For example, that's how I insert link controls in VS2005: as a custom control with class "SysLink".

MapDialogRect (mentioned in the article) is the function that Windows uses to translate the dialog units in the dialog resource to pixel units. MapDialogRect works (where GetDlgBaseUnits fails) because its given an actual handle to the dialog box, and can send it a WM_GETFONT message to retrieve the actual font the dialog will be rendered with.

Related

How to get correct background and control colors in property pages?

I'm trying to handle background color properly in a dynamically generated property sheet in dynamically generated property pages in win32 api using MFC (though I expect my question is general, and not restricted to MFC, but since my code and examples use it, it's germane to my question anyway).
So we have a:
CPropertySheet
containing multiple
CPropertyPage
I generate the contents of any given page dynamically - from file resources using a custom dialog definition language - all irrelevant other than to say - a list of controls and their coordinates is created within a given page, and the page is resized to accommodate them. This logic is working beautifully.
However, what doesn't work is that the controls and background of each page draws using the dialog default color/brush.
I've tried a number of ways to attempt to force it to draw using the white color/brush that a hard-coded property sheet / page would.
There are two important pieces to this:
Page Background
Control (on the page) background
For #1, I've tried:
acquire the background brush from parent window class (it's dialog bkgrd) (same is true if I do this and ask the tab control)
change the property page to use WS_EX_TRANSPARENT (PreCreateWindow is not called by the framework when generating a page viz PropertySheet::AddPage)
For #2, I've tried:
overriding OnWndMsg / WM_CTLCOLORSTATIC to forward that request to (A) the parent (sheet), and (B) to the tab control (which is what wants the white in the first place).
However, anytime I use any of the above "ask for the background / forward the request" up the chain to either the sheet or the tab control - I get the dialog background color, never the white I'd expect.
Using Spy64, I can see that for a fully hardcoded property sheet / page - that the only discernable differences I can see is that the dialog window created in AddPage (or its moral equivalent) has WS_CHILD instead of mine which has WS_POPUP (the rest of the styles appear to be the same, such as WS_VISIBLE|DS_3DLOOK|DS_FIXEDSYS|DS_SETFONT|DS_CONTROL and WS_EX_CONTROLPARENT.
So, other than the WS_CHILD, I see no significant differences from what I'm creating and from another property sheet that works properly from a standard resource (i.e. hard coded).
I'm also flummoxed as to how this works normally anyway - since forwarding things like the ctrlcolor message doesn't respond correctly - and asking for the windows background colors similar doesn't - then how is it in a standard case the background colors of controls and pages comes out as white, and not dialog background?
Any ideas or help would be appreciated - I'm kind of running out of ideas...
When Visual Styles were added in Windows XP they really wanted to show off this new feature so they made the tab background a gradient (really a stretched image) instead of a single color and this caused problems in old applications that did custom drawing with the dialog brush as the background.
Because of this, only applications with a comctl32 v6 manifest got the new look but there was a problem; old propertysheet shell extensions would load in new applications (including Explorer) and things would look wrong.
To work around this they also require you (or your UI framework) to call EnableThemeDialogTexture(.., ETDT_ENABLETAB) to get the correct tab page look.
As if things are not tricky enough, there is a undocumented requirement that you also need a button or a static control on the page!
If you have custom controls they have to call DrawThemeParentBackground when you draw if they are partially transparent.
Turns out my old code had defined an ON_WM_ERASEBKGND handler - and removing that (and all of my above attempts) makes it work.
So simply doing NOTHING is the correct answer. D'oh!!!
I'm leaving my shame here in case someone else trips on this! [Whoops!]
(Still interested if anyone has deeper insight into how this mechanism works under the hood)

How does modifying text highlighting work?

We are all familiar with text highlighting. You hover over any "text" in any application on your Windows OS, your cursor changes into an I-Beam, and you can click and drag across the text to Highlight it. This highlighted text can be copied to the clipboard for later use.
Some applications modify the default highlighting behavior by changing color, opacity, or even shape. Some applications allow for column selection (e.g. Visual Studio "alt-click-drag" creates box like highlighting)
I have scoured the depths of the internet, but I can't seem to find a solid source of information that would explain how one would modify the behavior of text highlighting.
How would I implement column/block text selection, and modifying the appearance of the highlighted text in a compiled application.
Since applications can do this in various custom ways, there is no single solution to change how all of them style text selections.
Many will rely on the current color scheme (using GetSysColor) to determine the highlight colors. So you could modify the scheme and maybe affect the colors used for many applications.
To do this programmatically, you would use SetSysColors to change the COLOR_HIGHLIGHT and COLOR_HIGHLIGHTTEXT values.
Other applications might rely on the current theme (using GetThemeColor). To affect those you'd have to select a different theme that has the colors (and perhaps other styling choices) that you want.
A lot of apps use their own hard-coded color schemes, so you won't be able to programmatically at all.
I'm not sure what you mean with the web application part of your question. A web application is some HTML, JS and CSS that make the browser interact with your system. Any custom selection (coloring) logic that the web application provides, has to be implemented by the browser.
Also you have to realize that "(text) selection" is an rather virtual principle. An application can just render a colored shape (like a blue rectangle) and copy something to the clipboard when it receives a WM_COPY message.
Windows provides in basic substring selection functionality for (rich) edit controls (i.e. start and end position), but for something custom like column selection, custom code is required.
Read more about this in Making a rectangular selection in a RichTextBox with Alt-Left-Mouse sweep?.

MFC colored button with native win7 appearance

I am using MFC to create a dialog project and trying to impart color to the buttons.
I came to know that the only way you can do is to make the button owner draw. OnCtlColor() does not work for buttons.
I am able to color the button overriding OnDrawItem , but the problem is that , in the process the 3D cool look (with slightly rounded corner that you get in Win7) is lost.
Is there any way to retain the native look and color the button on top of that?
This is not a trivial task. As long as you are using themed controls (what you want), you cannot do more than the theme allows.
You would have to re-implement drawing of the button on your own, making use of the theme API as much as possible to retain themed look, yet sneak-in your color.
Though note that you can hardly achieve anything better than, what .NET WinForms do, when you set the Button.BackColor:
See also question how to set Button BackColor?
Disassembling the WinForms ButtonStandardAdapter.PaintWorker will give you some idea and API you need to use. Beware, you need to do lots of coding!
For C++/MFC code check out Vista themed Owner-Drawn and Full-Custom Push/Menu/Image Buttons on CodeProject. Which probably actually does, what you want already (the SetBackgroundColor method), so you might reuse it.

find a better control to display book content in a e-book reader

I want to create an e-book reader app, I have tried to use the control RichTextBox to display the content of a chapter in a book, while, it could not display the entire chapter, finally, I am told that the size of any control in windows phone is less then 2048px, and this causes the text located after 2048px (Height) in the RichTextBox could not be displayed. So, I need to find another one control to do such a thing. Is there any suggestion?
Further more, I want the control may meet the following requirements:
it could customize the fontsize, forecolor of the text displayed in it (this may be the simplest one)
it could customize the background pic.
it allow the user to select the text on it freely for copy (this is the most important one of the 3)
Since an ebook is fundamentally a set of HTML pages, you should display your pages using a web control.
By the way, customizing font size etc. is not by any means trivial, because you end up trying to figure out whether or not and how to override CSS rules in the book.
You might want to check out http://openbookreader.codeplex.com/, although it seems to have been inactive for a couple of years.

Ribbon GUI Guidelines

I am thinking of implementing a ribbon GUI in one of my apps and of course want to adhere to the MS Guidelines so it feels like a normal ribbon, etc. But I'm trying to figure out how to solve a specific problem in dynamically changing the ribbon.
I'm creating a concept game editor, please no question on why a ribbon as this is purely a concept idea, but the application will have many editors (2D, 3D, Code, etc) and for each one the GUI should adapt and display relevant controls i.e. in the 2D editor maybe a paintbrush, on the 3D many pan and rotate tools.
Given the ribbon guidelines it makes sense to the Home menu to contain the most common tools, but only for the type of object being edited (rotate makes no sense for 2D or Code!).
I initially thought it could have one window per editor but this makes a real mess and I'd rather have lots of tabbed editors so you can flick through them fast like in eclipse etc. Also all editors save back into one file so it makes sense to have one application window to keep this metaphor for the user.
I was thinking I could dynamically change the ribbon tabs depending on what type of editor the user had open (tabs may appear/disappear, content on the Home tab etc would change) but then this breaks the MS guidelines of:
"Controls displayed in a group MUST NOT change as a result of selection. If a control is not active, then the control MUST be grayed out, rather than removed from the group"
"The tab selected on the Ribbon MUST NOT automatically switch as a result of user selections made in the 177 document (except as noted in the Contextual Tabs section)."
I understand the reasoning behind the guidelines but im not really sure how to get the ribbon to feel right in this situation:
Change the content of the tabs
depending on editor type (goes
against the guidelines)
Have a tab
per editor type (but what if i end up
with 15 editor types!)
Have a very
generic ribbon and move specific
editor operations to a side bar or
something (not the best GUI design)
Use contextual tabs for each type of
editor (better solution but means you
always have one contextual tab open!)
Any other ideas/solutions would be greatly appreciated as I must use a ribbon and must use it for this type of application!
If you are providing a tab that is editor-specific, I suppose you could lay it out in the way that is best for that particular editor. That means that controls are going to move around occasionally, if you use the same tab for the other editors. It doesn't seem practical to gray out the controls that don't apply to any particular editor, if it's going to cause a lot of clutter.
On the other hand, graying out controls does have the benefit of keeping each control in exactly the same physical place on the tab. Do not underestimate the power of this. There's nothing more aggravating than expecting a control one place, and having it suddenly move someplace else (or disappear altogether). The graying out is a clear indication that the grayed control does not apply in this context.
So depending on how different the controls are for each editor, you will have to decide which approach is less disruptive: to gray out the unneeded controls, or to provide a fresh layout for each editor.
It doesn't seem workable to open a tab for every editor that's open, since there will be many tabs that are useless when the user is in a specific editor.
If possible, enlist the help of some volunteers or beta testers, and do some paper prototyping with them to see which approach resonates better with them.
I'm facing the same design problem. One idea is to use different frame for each editor and a different specialized ribbon in it. Because there's little point in a big ribbon with 10 tabs full of disabled commands.
P.S. I'm investigating another idea - to use certain tabs clicks for triggering different editor modes. (I'm designing a house drafting program.) In example:
Clicking "Home" tab switches to the
plan editor to the edit the house
from "top" view;
Clicking "Wall"
tab switches to the wall editor
where you can edit the wall shape
and featues.
Clicking on other tabs
may not change the current editor.
They can show up other non-modal
commands that are related to the
whole document (or something else),
not about the current editor mode
itself.

Resources