Place a window behind any other existing third party window - windows

In order to take a screenshot of a specific window, I need to place a white colored TForm behind that window. What Windows API could I use to change the z-order of my window and place it correctly ?

Try the SetWindowPos() function.

On Delphi you can useSendToBack method, .Top and .Left properties.
form1.Top := ...;
form1.Left := ...;
form1.SendToBack;
procedure SendToBack;
Description
Use SendToBack to change the order of
overlapping controls or forms.
The order in which controls stack on
top of each other (also called the Z
order) depends on the order the
controls are placed on the form. For
example, if you put a label and an
image on a form so that one is on top
of the other, the one that was placed
first on the form becomes the one on
the bottom. Because both the label and
the image are non-windowed controls,
they "stack" as you would expect them
to. Call the SendToBack method for the
top object to move it below the other
object.
The stacking order of two windowed
controls is the same as the stacking
of two non-windowed controls. For
example, if you put a memo on a form,
then put a check box on top of it, the
check box remains on top. Calling
SendToBack for the check box makes the
memo appear on top.
The stacking order of windowed and
non-windowed controls cannot be
mingled. For example, if you put a
memo, a windowed control, on a form,
and then put a label, a non-windowed
control, on top of it, the label
disappears behind the memo. Windowed
controls always stack on top of
non-windowed controls. In this
example, calling the SendToBack method
of the memo does nothing, the label
remains behind the memo.
If the control has the input focus
when the SendToBack method executes,
it loses the input focus.
(Edit: WinSnap is a very good utility for taking and editing screenshots)

If you can get the handle of the window you want in front then I would assume that:
Pseudo Code:
MyAppWindow.BringToFront
followed by
TargetWindow.BringToFront
Should have the desired effect, yes?

Related

MFC: limit the size of child control from the code of control itself

Say, I have a CListCtrl-derived control. I want it to be always square (i.e. it's width and height should be always equal to each other).
The control resides on a dialog (CDialog-based), it is resized once the dialog is resized (the control is resized using SetWindowPos()). What I want to achieve is to make it impossible to resize the control improperly: the control must always have equal horizontal and vertical dimensions regardless of what is passed to SetWindowPos.
Of course, I can control the values that are passed to SetWindowPos. The question is: is it possible to control the size of the CListCtrl-derived control inside the code of that control itself?
If you subclass the control and have it handle the WM_SIZING message you can constrain the resize in any way you'd like. Just modify the RECT structure that's passed with the message.

Treeview control in Win32 API - how to display a single treeview item using different fonts?

I'm faced with a problem where I need to display some characters in a tree-view item (those belonging to the Symbol charset) using Symbol font while others in the default System font (Segoi UI on my Windows 7).
Custom draw allows us to draw different items using different fonts, but I would like to draw the same item string using different fonts as it applies to each character in the string as told above.
So, what I've done with not-so-pleasing results w.r.t. drawing performance upon a horizontal scroll when the number of items is more so far is this:
I disabled horizontal scrolling in my tree-view control using TVS_NOHSCROLL style (since I'm using my own scroll bar control inside the tree-view window to handle all horizontal scrolling)
I sub-classed the treeview control and in the sub-classed winproc, I handle the horizontal scroll notification and mouse notification (where I do my own hittesting and send message like TVM_EXPAND and TVM_SELECT as a result of mosue clicks/double-clicks). Also the scroll bar range is set based on how wide my custom drawn string is (the maximum length amongst all items).
I draw the string for each item upon receiving CDDS_ITEMPOSTPAINT using my own fonts for each character in the item.
The above approach (I left out some details for the sake of brevity) works BUT there are some problems which makes me post this question here and look for an alternare way:
Problems:
The horizontal scroll bar control I create is hosted "inside" the tree-view control at the bottom of the tree-view window. However, when the number of items goes beyond what the tree-view client area can accommodate vertically, the last visible tree-view item gets obscured by the scroll bar control. This can be solved by not making the scroll bar a child of the tree-view and hosting it outside the tree-view window just below it. But I don't want to do this since the scroll bar should typically be a child window of the tree-view.
This is the major one. Since I draw the items myself at each horizontal scroll, the drawing performance upon horizontal scrolling is very slow and also leads to flicker upon scrolling.
Any ideas will be much appreciated as I've been grappling with this for the last one week without success.
I can also post the relevant code here if you want to see the approach I took but I'm sure there shoould be a better approach to this and there must be some other people who would've faced this problem and solved it in the past.
Thanks in advance.
Custom-draw allows you to draw items however you want. You are not limited to a single font per item. When you receive the NM_CUSTOMDRAW notification, draw whatever you want on the provided HDC for the specified item. You can draw pieces of text in one font, pieces of text in a different font, etc. Be sure to return CDRF_SKIPDEFAULT so the TreeView itself will not try to draw anything on the item.
#Anurag S Sharma: I tried to edit this into Remy's answer. It's incomplete as is, but addresses your comment/concerns and answers this particularly vexing/useful question...
The problem is that ff I return CDRF_SKIPDEFAULT, Windows does not even draw the +/- buttons (expanding/collapsing) nor the indent lines in the control which I do want Windows to draw. – Anurag S Sharma
To retain the lines, buttons, and icons you can use ExcludeClipRect to mask only the text region and instead of returning CDRF_SKIPDEFAULT, return 0 as if you didn't draw anything. This itself would not be necessary if the text of the tree item was empty, except that the margins of the text will always be drawn by the default handler (note that Microsoft's controls do not always respect clipping shapes, but in this case they do.)
To replicate the classic TreeView label style in your custom draw procedure you need to do something like the following:
HTREEITEM item = (HTREEITEM)p->dwItemSpec;
TreeView_GetItemRect(p->hdr.hwndFrom,item,&p->rc,1);
RECT cr, rc = p->rc; GetClientRect(p->hdr.hwndFrom,&cr);
DrawTextW(p->hdc,text,-1,&rc,DT_CALCRECT|DT_NOPREFIX|DT_NOCLIP);
rc.right+=4; rc.bottom+=2; IntersectRect(&rc,&cr,&rc);
ExtTextOutW(p->hdc,rc.left+2,rc.top+1,ETO_CLIPPED|ETO_OPAQUE,&rc,text,wcslen(text),0);

Implementing scroll in custom drawn control in WTL

I have created my own custom drawn list with checkboxesin WTL, I want to make it scrollable now, the thing is that I am subclassing a Static Text control over which I draw.. And I don't know if static controls support scrolling in any way..
Anyway my question is how do I make my custom made controll scrollable, do I have to impement the mechanism myself?
Yes, you'll have to implement it entirely by hand. That's the drawback of not using a built-in control. It probably would have been a better idea to start off with a ListBox and then customize that to your desire. That way, you would get all of the scrolling, selection, and other logic for free.
The steps are roughly as follows (there are probably ATL/WTL idioms for some or all of these, but any ATL/WTL programmer can convert back and forth from raw Win32):
Add the WS_HSCROLL and/or WS_VSCROLL window styles to your custom static control, depending on if you want a horizontal, vertical, or both scroll bars. You would add these to list of window styles passed in to the CreateWindow/CreateWindowEx function.
By default, those scroll bars won't do anything at all. You need to tell them what to do using the SetScrollInfo function. In your case:
The first parameter (hwnd) would be the handle to your control window.
The second parameter (fnBar) should be either SB_HORZ to adjust the horizontal scroll bar, or SB_VERT to adjust the vertical scroll bar.
The third parameter (lpsi) is a pointer to a SCROLLINFO structure, filled in with the desired scrolling parameters, including the current position of the thumb, the minimum and maximum values, and the "page" size used to set up the proportional scroll bar.
The fourth parameter (fRedraw) should probably be set to TRUE.
You will also need the EnableScrollBar function to enable/disable the scroll bar as appropriate. Like the previous function,
hwnd is a handle to your control window
wSBflags is either SB_HORZ, SB_VERT, or SB_BOTH
wArrows is one of the ESB_* values, depending on what you want
Finally, you will want to write code in your custom control's window procedure to handle the WM_HSCROLL and/or WM_VSCROLL messages. These are sent to the window whenever the scroll bar is moved. Inside of the handler for these messages, you will want to do the following things to update the control's state:
Call the SetScrollInfo function to update the thumb to its new position
Redraw the contents of your control in accordance with the scrolled distance. There are multiple ways of doing this, but I'd probably use the ScrollWindowEx function.
The custom control's window procedure will also need to handle the WM_SIZE message to update the scroll bar state (by calling SetScrollInfo and/or EnableScrollBar) in response to changes in the window's size.
Cody Gray provided excellent introduction into adding support for scrolling, however what you also have is the help from the WTL itself.
WTL's atlscrl.h offers you classes to inherit from and implement a custom window/control with scrolling.
// Classes in this file:
//
// CScrollImpl<T>
// CScrollWindowImpl<T, TBase, TWinTraits>
// CMapScrollImpl<T>
// CMapScrollWindowImpl<T, TBase, TWinTraits>
// CFSBWindowT<TBase>
// CZoomScrollImpl<T>
// CZoomScrollWindowImpl<T, TBase, TWinTraits>
// CScrollContainerImpl<T, TBase, TWinTraits>
// CScrollContainer
Not so much code/snippets around to demo the use, but there is still one WTL sample that covers the basics and it should be a good starting point for you as well. \Samples\BmpView has a class for scrollable bitmap:
class CBitmapView :
public CScrollWindowImpl<CBitmapView>
{
public:
You will see it's really small and it covers most of the complexity.

How to show the picture box in front of textbox, combo box inside the Frame?

Using VB 6
Am using Frame, Inside that frame am using textbox, combo box, labels.
When I am running the project it will show like "processing".
So I used the picuture box also inside that frame. But Picture box is not showing in the front of textbox, combobox, labels.
I tried, but it is showing only the picture layout, it is not showing the label “processing”
How to set a property for this condition.
Exactly i need, while executing the program it will show like processing then it will display a output.
Need VB 6 Help
A label component does not have a window handle -- hWnd, but instead is drawn right on its parent (in this case, the frame component it sounds like).
A combobox, a textbox, and a picturebox all have a window handle (hWnd), so can have a zOrder and appear behind/in front of other components.
I believe the answer to your question is to place the label component inside a picturebox, and then set the zOrder of the picturebox as needed.
It sounds like your label is underneath one of the other controls (your question isn't particular clear) - if that is the case, you need to play with the ZOrder property of your controls to be able to decide which control gets to be on top (i.e. to be displayed). This link gives you an example of how to use this property.

How to paint transparent areas for child controls?

I have a CTabCtrl subclass which I'm trying overriding WM_PAINT to perform custom drawing. The only problem is, when I change the selected tab, I get artifacts left on the dialog where the old paint code hasn't been erased before the new code is painted on top. (The standard tab controls have the selected tab appear 2 pixels bigger than non-selected tabs, so when you change from selected to non-selected, you are left with the previous paint artifacts).
What is the best way of "repainting" this area? I've tried getting the parent control's DC and BitBlt'ing that onto the child's DC, but that doesn't work because the parent DC already contains an image of this control.
Do you override the WM_ERASEBACKGROUND message as well? You should probably do that and erase the area in the control.
You could use DrawThemeParentBackground to draw the background (XP and later) if you don't want to replace all the drawing logic.

Resources