i am writing in WinApi/MFC my own control CCustomComboBox , which inherits from CComboBox, and i would like to draw in items instead of putting into them only a text.
I achieved this by defining a style CBS_OWNDERDRAWVARIABLE and then draw in OnDrawItem function, but i don't know how to draw on a main window of ComboBox( select item).(the window on the top of combo box)
I can call on it for example SetWindowText() but I would like to draw anything on it for example LineTo().
In general i would like to copy what is drawn on a particular item of combo box to edit/main item.
But to do this first i would like to know how to draw on it.
Thanks for advices!
Przemek
Related
I am a rookie Cocoa guy. I need to design and implement a view which will show collection of labels on Mac OS using Xamarin. These labels will have a text and color associated with them. When shown inside the view, label should expand till it covers whole text and it will be shown with background and foreground colors.
I have attached the picture of this user control on Windows, you can see that labels inside the StackPanel are expanding till they cover the whole text. Hope this gives better idea about my ask.
The $64,000 question is "are these labels controls?" In other words, do you expect the user to click on these to do something, or are they just for display?
If your answer is "just for display", the solution is super simple: Use an NSTextField and programmatically add attributed text (NSAttributedString) to it. Attributed text attaches display properties to runs of text within the field; properties like "background color".
If you want these to be buttons that you can click on, then things get a lot more complicated.
Since you apparently want the button layout to "flow", you might look into imbedding buttons (well, button cells) into an NSTextField using attachments. This is normally how non-text content (say, an image) can be inserted, but with some fiddling it can actually be anything a control cell can draw. See How to insert a NSButton into a NSTextView? (inline).
Warning: this is not a "rookie" topic and will involve control cells and custom event handling.
If I were doing this, I'd probably just create NSButton objects for each label (choosing an appropriate style/look like NSRecessedBezelStyle), create a custom subclass of NSView to contain them, and then override the layout method to position all of the buttons the way I want.
To be thorough, I'd also override the intrinsic size methods so the whole thing could participate in auto-layout, based on the number and size of buttons it contained.
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);
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?
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.
I'm trying to make the cells of a QTableView look like 3D clickable buttons. So that when you click on a cell, the button looks pushed. Everyone seems to think I merely want to change the colour, I need to show images of a normal button, and a pushed button, that look 3-dimensional.
I have done this already with calling QTableView::setItemDelegate(), with an appropriate ItemDelegate that will change the background of the cell when it's clicked. However I'm stuck at this point because I want some cells to be different coloured buttons based on the data they contain. So a cell with a low number would be a red button, that's also red when it's clicked, and the other cells would be different colours.
I can set the colour of the button with the TableModel, but once the button is clicked, there is no way for the ItemDelegate to know that it's supposed to be a different colour than the rest. How can you link the two so the ItemDelegate knows what colour it's supposed to be?
Also, is there simply a better way to make cells look like buttons?
You can call QModelIndex::model() from within the ItemDelegate's paint() method, since it has a QModelIndex parameter. This gives you the TableModel for the data, which you can programatically decide what colour the cell's button will be.
However, this is still not as elegant as I'd hope. Does anyone know a better way to change the appearance of table cells when in both the up and down button push states?
Why don't you asked the index for the background color.
Something like this ...
QStyleOptionToolButton buttonOption;
const QStyleOptionViewItemV4& optionV4 = dynamic_cast<QStyleOptionViewItemV4&>(option);
//...
buttonOption.palette.setBrush( QPalette::Button, index.data( Qt::BackgroundColorRole ) );
//...
I have feeling that its a bug in Qt and its must have been ...
// model code
if(role==Qt::BackgroundColorRole )
return qvariant_cast<QBrush>( QBrush(Qt::red) );
// delegate code
buttonOption.palette.setBrush(QPalette::Button, optionV4.backgroundBrush );
Because the optionV4.backgroundBrush is correct in the sizeHint method but is invalid in the paint method . I see now reason why the sizeHint should have the background brush and the paint method not. I'll report it to Nokia.
EDIT:
Looks like I was right and its a bug in < Qt4.5.
QStyleOptionViewItemV4 doesn't copy the icon and backgroundBrush
Can you not get the ID/row count of the table cell's row and then check it against the colour table that you may be having, and set the colour accordingly? I am not sure if I understood your question well or not.
Assign a data role for the background color, and in your item delegate, ask the model index what it's background color is (using data( bg_color_role ) or something similar). Then, in your model, you need to make sure the data function returns a color for the bg_color_role that is appropriate for the data being modeled.
The way to do that is to use the data method of the QModelIndex object you get on the paint method, and ask for a specific role (if you define a custom model, you can add your own roles, and give the information you need to the delegate in those roles.)
TimW, I think you have to fill the QStyleOptionViewItemV4 info by calling initStyleOption before.
I'm not sure where the requirement for a background image comes from. If you want the cells to look like QPushButtons, you should probably inherit from QItemDelegate and implement paint() to use QStyle to draw you a QPushButton, something like this:
QStyleOptionButton opt;
// fill 'opt' from the information from the model, and the style option that's passed in
style()->drawControl( QStyle::CE_PushButton, &opt, painter );
Have you tried using custom style sheets?
You could just apply the same stylesheet to every cell, and then change the background image / style to draw the 3D button images depending on whether or not it's selected.