RichEdit control doesn't show horizontal scrollbar when switching tabs - winapi

I have a tab control with some RichEdit controls. Whenever the active tab changes, I hide the RichEdit control belonging to the old page and show the RichEdit control belonging to the new page. This works except that the horizontal scrollbar of the RichEdit control doesn't show. When switching tabs, it looks like this:
As soon as I change the cursor position, however, the horizontal scrollbar suddenly appears and it looks like this then:
I've debugged what's going on and found out that the following code is responsible for making the scrollbar appear:
RedrawWindow(hRichEditWnd, NULL, NULL, RDW_FRAME|RDW_INVALIDATE|RDW_UPDATENOW);
The call to RedrawWindow is made by the code that implements syntax highlighting. This code is executed when changing the cursor position.
So I tried to simply call RedrawWindow like above when changing tabs but it does not work. The horizontal scrollbar still does not appear. However, when RedrawWindow is called later, e.g. in response to the user changing the cursor position, the horizontal scrollbar suddenly appears.
Any idea on how to fix this so that the scrollbar appears right when changing tabs?

After trying several things I've found out that calling ShowWindow before repositioning the dock windows and the RichEdit control solved the issue. Previously, I was doing something like this when switching tabs:
BeginDeferWindowPos();
...reposition and resize all dock windows and the RichEdit control ...
EndDeferWindowPos();
ShowWindow(hRichEditWnd, SW_SHOW);
When I call ShowWindow before BeginDeferWindowPos the issue is gone, i.e.:
ShowWindow(hRichEditWnd, SW_SHOW);
BeginDeferWindowPos();
...reposition and resize all dock windows and the RichEdit control ...
EndDeferWindowPos();
Don't ask me why this solves the issue, but it does.

Related

Win32 Dialog box: how to keep all objects in windows centered when resizing

I am building and maintaining a Win32 app using Visual Studio.
I have recently edited the .rc file adding WS_THICKFRAME to my dialog STYLE line for all dialog windows to allow them to be resizable.
My current problem is, when I resize a window, its content remains fixed to the left. How can I make the window's content remain centered when resizing using the border?
Pointing to any relevant documentation on this would also be helpful, as I have not had lucky finding that.
If you only want to reposition (rather than resize) the individual controls, an easy way would be to create a non-modal container dialog to hold the controls, make that dialog a child of the resizable dialog, and then when you handle WM_SIZE for the outer dialog, you only have to reposition that one non-modal dialog.
Your new position is ((newWidth- controlDlgWidth) / 2, (newHeight-controlDlgHeight)/2), where controlDlgWidth, controlDlgHeight are the width and height of the child dialog.
I say to use a non-modal dialog for this, so that you can continue using a resource script, rather than needing to add a whole bunch of explicit CreateWindow() calls.

scroll bar vertical on c++ builder

I´m doing a bit GUI, this has a Form with a TMemo with the property ScrollBars set to ssVertical but I would like that the vertical scroll only shows when necessary, at present it's always shown. How can I disable when not necessary and enable when necessary?
Thanks you very much.
Unfortunately, TMemo's scrollbars do not work that way. If they are enbled then they are always displayed, regardless of the content. Switch to a TRichEdit instead.

Weird black pixels in the corners of CProgressCtrl controls

I have an MFC dialog (actual a dialog bar with in a dialog) that contains a progress bar with these strange black pixels in the corner. I have tried the following to remove them:
Change most of the border type styles and the transparent style of the control.
Override the OnEraseBkgnd in a class derived a CProgressCtrl.
Setting the background color of the control by PBM_SETBKCOLOR.
I have yet to find a way to remove these black pixel.
Here is an example of what it looks like:
It seems I have found the issue. When the progress bar performs its painting it was sending an WM_ERASEBKGND message to the dialog to get the background with which it would paint. Some how the DC brush origin was being messed up. Using the following code at the start of the function seems to have fixed the issue with no ill effects.
CRect rcClip;
pDC->GetClipBox(rcClip);
pDC->SetBrushOrg(-rcClip.left, -rcClip.top);
I've seen this occur when using ActiveX controls inside control containers that don't have a a window or proper Device Contexts (The VB6 frame control is one of these) but I'm not sure if the same problem applies to MFC windows and controls though.
Try making the control parent a normal static window.

How to resize controls to fit the browser window in C#, Silverlight 4

I have a tab control in my main page. When I have it in the Design view in Visual Studio, everything looks perfect, the tab control is set to fill the entire page. However when I run the program, and I have it in a maximized browser window, the tab control is still the same size as it originally was. In other words, the tab control does not resize proportionally to the browser window resize.
So I was wondering if there was a way to change a setting on my tab control or maybe some code that would force the tab control to resize along with the browser window?
(Using C#, Silverlight 4.0 in VS2010)
Ok, so after tinkering with this for the last couple days, I've finally found the answer. I feel like a rookie for not doing this sooner, but I got to looking at the title bar on the top of the page and noticed that it stretched across the screen when the browser window was maximized and when it was resized, the title bar shrunk to fit. So I looked at the properties of the title bar and saw that it's horizontal/vertical alignment was set to "stretch." I know, it's a rookie mistake, but it just never occurred to me that "stretch" was an option in the alignment property.
Long story short, change the horizontal alignment property to "stretch," vertical alignment property to "stretch," and then set the height property of the control to "auto" and the width property to "auto" and you've got yourself an auto-resized control.

How to draw outside a window?

Looking at a Windows tooltips class hint window, i see that it draws its drop-shadow outside the hint window's actual rectangle.
Using SpyXX - i can get the tooltip's window rect, and class styles:
Rectangle: (440, 229)-(544, 249), 104x20
Restored Rect: (440, 229)-(544, 249), 104x20
Client Rect: (0, 0)-(104, 20), 104x20
You'll notice that the drop shadow you see is physically outside the window that's being drawn. How can i draw a shadow outside around my window, while being outside my window?
Note: The shadow is not drawn using the standard CS_DROPSHADOW class style. i've confirmed this experimentally, and can also see the class style's for the window in SpyXX; it does not use CS_DROPSHADOW:
Windows Styles: 94000001
WS_POPUP 80000000
WS_VISIBLE 10000000
WS_CLIPSIBLINGS 4000000
TTS_ALWAYSTIP 1
Extended Styles: 00080088
WS_EX_LAYERED 80000
WS_EX_TOOLWIN 80
WS_EX_TOPMOST 8
So how can i draw outside my window?
Note: Trying to draw on the desktop DC is out. From Greg Schechter's Redirecting GDI, DirectX, and WPF applications:
Drawing To and Reading From the Screen
-- Baaaad!
Lastly, since we're on the redirection
topic, one particularly dangerous
practice is writing to the screen,
either through the use of GetDC(NULL)
and writing to that, or attempting to
do XOR rubber-band lines, etc. There
are two big reasons that writing to
the screen is bad:
It's expensive... writing to the
screen itself isn't expensive, but it
is almost always accompanied by
reading from the screen because one
typically does read-modify-write
operations like XOR when writing to
the screen. Reading from the video
memory surface is very expensive,
requires synchronization with the DWM,
and stalls the entire GPU pipe, as
well as the DWM application pipe.
It's unpredictable... if you somehow
manage to get to the actual primary
and write to it, there can be no
predictability as to how long what you
wrote to the primary will remain on
screen. Since the UCE doesn't know
about it, it may get cleared in the
next frame refresh, or it may persist
for a very long time, depending on
what else needs to be updated on the
screen. (We really don't allow direct
writing to the primary anyhow, for
that very reason... if you try to
access the DirectDraw primary, for
instance, the DWM will turn off until
the accessing application exits)
You can't draw outside your window in the manner you describe.
If you right click your desktop then go to properties/appearance/effects and uncheck 'Show shadows under menus' ... you will no longer have the shadow.
Bottom line is that this is a product of the window manager not your program.
Q: How do you draw outside of one window? A: Draw inside another window!
First thing to note is that the tooltip class actually does use the CS_DROPSHADOW style - but note that this is a class style, not a window style, so you have to look at the Class tab in the Spy++ properties dialog to find it. You'll see that the tooltips_class32 windows does indeed have this - and a few others.
But that just leads to the next question - how does that work? Well, it seems that Windows implements this by creating a helper HWND to draw the shadow - presumably it's creating another popup window the same size and shape as the one it's shadowing, filling it with gray, placing it directly underneath the main window, and setting it as a WS_EX_LAYERED window so that the shadow can be transparent and fade out around the edges using alpha-blending. And there's nothing to stop you from using the same or similar techniques yourself if you want to add a different type of shadow effect to one of your own windows.
So, long story short: if you want to draw outside of your own window, create a helper transparent window in the general area that you want to draw on, and draw on that helper window instead.
--
Now, if you try to find one of these helper shadow windows in Spy++, you won't find much. Unlike the tooltip_class32 windows, which are long-lived and just hide/show themselves as needed, these shadow windows are a more elusive creature: they are only created for as long as needed, so you'd have to refresh Spy++ while there's a tooltip or popup menu or other window using the shadow present - and that's tricky, since most tooltips and menus will disappear as soon as you move the mouse to switch to Spy++. But it turns out that the tooltips on Spy++'s own toolbar will stick around: so start Spy++, hover over an item in the toolbar, and hit F5 to refresh the HWND tree while the tooltip and shadow are present. Now scroll down, and you should see the third and fourth visible HWNDs in the tree are the tooltip itself, and right after that, a SysShadow window. Unfortunately, since the tooltip and shadow have by now disappeared, if you attempt to get the properties dialog for that HWND, you'll get a get a blank property dialog with an 'Invalid Window' message. If you really want to poke around and see how that SysShadow works, what styles it itself uses and so on, you could create a target app with a long-lived popup that uses CS_DROPSHADOW that you can then explore in Spy++ at leisure.
(Finally, note that these shadows are a completely different thing than the shadows that you see when one app window is on top of another above another since Vista: this type of shadow is part of Aero Glass mode, and handled by the same Desktop Composition Manager that adds the glass titlebar effect, and it doesn't use or need helper windows to implement the shadows.)
I wouldn't be surprised if that shadow is intimately tied to the window manager itself; it is after all the window manager who decides what window gets to paint which parts of itself and when it can do it. I don't see it as rocket science to paint that shadow if control over all that is gained, which the window manager has.

Resources