How to draw the static part of the combobox - winapi

I have a custom drawn combobox with style CBS_DROPDOWNLIST and CBS_OWNERDRAWVARIABLE I can draw the items of the dropdownlist ok but whe user select an item it is drawn in the combobox static part [the part of combo that stay visible after selecting item and show the selection], I want to give it a custom text like in the following image
But I can't determine it I found a code like this
if(DrawItemStruct.CtlType == ODT_COMBOBOX)//the static part of the combo
DrawComboText(pDC, DrawItemStruct.itemID, &DrawItemStruct.rcItem);
else//the rest items
{
// Copy the text of the item to a string
char sItem[256];
GetString(sItem, DrawItemStruct.itemID);
biDrawText(pDC, sItem, -1, &DrawItemStruct.rcItem, f | DT_VCENTER | DT_SINGLELINE);
}
but when I used it I get all the items has CtlType == ODT_COMBOBOX, when I debugged the above code It return ODT_COMBOBOX for the static part, and for items of the drop down list it return ODT_LISTBOX.
I want to know how to fix this problem, how to detect that I'm drawing the static part or a regular item in the dropdown list?

I just check the state for ODS_COMBOBOXEDIT. If ifthe dcumentation says that this flag is set for the edit Control, it works for the drop down list to.
I have checked combo box implementation like you that works in the sane way.
bool bDrawStaticControl = (pDIS->itemState & ODS_COMBOBOXEDIT)!=0;

Related

TableView - Display Image If Cell Boolean Value Is True

My TableView is populated with data from a list of objects. The first column is a Boolean value.
Instead of displaying True or False in the cell, I would like to display an image if True and leave the cell empty if it's False.
This is how I populate the TableView:
colStarred.setCellValueFactory(new PropertyValueFactory<>("starred"));
colDate.setCellValueFactory(new PropertyValueFactory<>("date"));
colTime.setCellValueFactory(new PropertyValueFactory<>("time"));
I know that I need to use a custom TableCell and a CellValueFactory but I'm having a hard time wrapping my head around the documentation (I have not used Java factories in the past).
My research has lead to several answers regarding similar situations, but they all seem to deal with just displaying an image in the cell. I have been unable to find a solution for checking a boolean to determine whether an image should be displayed or not.
How do I check the starredProperty of my objects and show an image if it is True?
Thank you for all the help everyone has provided me in the past!
I'll assume the column to be a TableColumn<MyItemClass, Boolean>.
You simply create TableCells that adjust their look according to the item that gets passed to the updateItem method.
In this case we'll use a ImageView as graphic of the cell.
The following images are displayed depending on the item of the cell:
no image if the cell is empty or contains null
imageTrue if the item is true
imageFalse otherwise
You may of course use imageFalse = null for an empty cell when the item is false.
final Image imageTrue = ...
final Image imageFalse = ...
// set cellfactory
colStarred.setCellFactory(col -> new TableCell<MyItemClass, Boolean>() {
private final ImageView imageView = new ImageView();
{
// initialize ImageView + set as graphic
imageView.setFitWidth(20);
imageView.setFitHeight(20);
setGraphic(imageView);
}
#Override
protected void updateItem(Boolean item, boolean empty) {
if (empty || item == null) {
// no image for empty cells
imageView.setImage(null);
} else {
// set image for non-empty cell
imageView.setImage(item ? imageTrue : imageFalse);
}
}
});
What happens when the program is displayed is this:
The TableView creates cells needed to display the items using the cellfactories.
The TableView assigns the items to the cells. These items may be changed multiple times. Cells may also become empty after being filled. When this happens the updateItem methods of the TableCells are called.

E4 RCP How to set selection of ToolBarItem that contains Radio Buttons

In Eclipse E4 (Luna), using the application model to create parts, handlers, commands, handled menu items etc, (these are not created programatically). I have a toolbar. This contains a sub-Menu item called "Filter" that contains another sub-menu of two filters. The two filters are two Handled Menu Items which are set up as "Radio" Buttons.
When I select the appropriate in the UI of my running app from the selection, the Radio button switches just fine to the selected Item. However I would like this selection to update (deselecting one Radio button and selecting the appropriate radio button of the handled menu item) when my ViewPart changes through other UI selection. Currently my ViewPart updates, but the Radio buttons are on the same previous selection through the UI.
Is there a way in which I get access both Handled Menu Item's IDs and set the selection (one to false, the other to true) when the viewer is updated.
Image of design is attached below:
Hierarchy of the application model is as follows:
Thanks in advance,
Marv
You can use the model service to find menu items. Use something like:
#Inject
EModelService modelService;
#Inject
MApplication app;
List<MMenuItem> items = modelService.findElements(app, "menu item id", MMenuItem.class, Collections.emptyList(), EModelService.IN_MAIN_MENU);
Once you have the MMenuItem you can call the setSelected(boolean) method to change the selection.
To find a menu item which is in a Part menu use:
modelService.findElements(app, "menu item id", MMenuItem.class, Collections.emptyList(), EModelService.IN_PART);
(IN_PART argument instead of IN_MAIN_MENU).
You could also specify the MPart rather than the Application as the first argument to findElements which may speed up the search.
For menus as a child of a Tool Bar Item it appears that the model services cannot find these directly. However you can find the Tool Bar Item and look at the menu yourself:
List<MToolItem> items = modelService.findElements(app, "tool bar item id", MToolItem.class, Collections.emptyList(), EModelService.IN_PART);
MToolItem item = items.get(0);
MMenu menu = item.getMenu();
List<MMenuElement> children = menu.getChildren();
... search menu elements
I solved this by starting with MPart PartID and drilling down to the HandledMenuItems on which I wanted to set the Radio Button selections, then setting the selection property for each individual HandledMenuItem.
This can probably be refactored to be more concise, but I've left the code with each step to have the solution easier to read.
BTW, in every instance / combination of the EModelService methods, the list returned a size of 0. So I'm not certain if that will work for what I'm trying to achieve. The following does work, although I'm not certain it is the most efficient means.
I hope this helps others.
// Get view part
MPart viewPart = _partService.findPart("part_id");
// get list of all menu items from the Part
List<MMenu> viewPartMenu = viewPart.getMenus();
// Get list of ViewMenus from viewPartMenu there is only one View Menu so it will be index 0
MMenu viewMenu = viewPartMenu .get(0);
// Get list of MMenuElements from the viewMenu - the children in the view menu
List<MMenuElement> viewMenuElements = viewMenu.getChildren();
// This gets me to the 2 HandledMenuItems
// Upper Most HandledMenuItem Radio Button is at viewMenuElements index 0. This is cast to MHandledMenuItem
MHandledMenuItem upperHandledMenuItem = (MHandledMenuItem) viewMenuElements.get(0);
// Set Selection
upperHandledMenuItem.setSelected(false);
// Lower Most HandledMenuItem Radio Button is at viewMenuElements index 1. This is cast to MHandledMenuItem
MHandledMenuItem lowerHandledMenuItem = (MHandledMenuItem) viewMenuElements.get(1);
// Set selection
lowerHandledMenuItem.setSelected(true);

Placeholder still visible when adding edit control to a CToolbar?

Years ago, I added an edit control to the toolbar in my application following directions similar to these:
http://www.codeproject.com/Articles/1106/Adding-a-Combo-Box-to-a-Docking-Toolbar
Similar directions can be found in many articles, so I think the procedure is fairly common. Until a few years ago, this worked fine, and the result was as shown in the article. However, I believe the move to XP changed the appearance of buttons in the toolbar, and instead I now see this in my application:
It seems as though the original instructions worked only because controls prior to the change occupied the entire height of the toolbar, so the edit control obstructed the separator behind it.
Ideally, I think the underlying separator should be made invisible. However, this doesn't seem to be handled explicitly in any of the articles I've found, and I'm not quite sure myself how to prevent the separator from being drawn.
Any help would be greatly appreciated. Thanks!
If you follow that article on codeproject exactly, you have probably modified the place holder into a separator from a button. This is why the separator line shown thru when the height of the button image is bigger than the height of the combo box.
If you keep the place holder as an empty button, you will not have such problem. A series of several place holder buttons may be needed in cascaded formation for a really useful length for the combobox.
This technique is demonstrated as follows:
// standard creation of the toolbar in CMainFrame::OnCreate
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
// status bar creation .....
// .....
// the place holders are a series of 5 empty toolbar buttons ie: ID_COMBO_1 to ID_COMBO_5
// get index of first combobox place holder
INT nIndex = m_wndToolBar.GetToolBarCtrl().CommandToIndex(ID_COMBO_1);
// get size of first place holder rectangle
CRect rcRect;
m_wndToolBar.GetToolBarCtrl().GetItemRect(nIndex, &rcRect);
INT nWidth = rcRect.Width();
// calculate width of combobox with sum of all place holder (5 in total)
nWidth = nWidth * 5;
rcRect.top = 5; // top of combo box
rcRect.bottom = rcRect.top + 250; // drop height
rcRect.right = rcRect.left + nWidth;
// create the combobox to sit above the place holders
if(!m_comboBox.Create(CBS_DROPDOWNLIST | CBS_SORT | WS_VISIBLE |
WS_TABSTOP | WS_VSCROLL, rcRect, &m_wndToolBar, ID_COMBO_1))
{
TRACE(_T("Failed to create combo-box\n"));
return FALSE;
}
m_comboBox.AddString("Toolbar Combobox item one");
m_comboBox.AddString("Toolbar Combobox item two");
m_comboBox.AddString("Toolbar Combobox item three");
I've used this technique from CodeGuru. It's old, but, I've been using it for many years and it still works.

How to retrieve the controls inside the selected item from a listbox in WP

I'm now facing the most common problem faced my many while working with listboxes. Though I found many answers the the forum, nothing seems to work for me or else i have got it wrong. .
I have created a listbox through code. Every listbox item has a stackpanel and within it two textblocks. the stackpanel has vertical orientation.The foreground of the textblocks have been set to specific colors. When an item has been selected or clicked it moves to another page and on the close of the new page it returns to the old page.
My problem is that, when a listbox item has been clicked, it does not show the selection color which is by default the phones accent color before moving to the next page. Is it because the color of the textblocks have already set while creating the listbox?
So i tried to set it the foreground of the selected item through the SelectionChanged() like this
ListBoxItem selItem = (ListBoxItem)(listboxNotes.ItemContainerGenerator.ContainerFromIndex(listboxNotes.SelectedIndex));
selItem .Foreground = (SolidColorBrush)Application.Current.Resources["PhoneAccentBrush"];
But this does not work, and i assume its cuz there is a stackpanel inside the item.
How exactly this needs to be done? Do i need to retrieve the textblocks inside the stackpanel and set the foreground?? I have not used binding here. Visual Tree Helper???
Thanks
Alfah
In general, the selected color doesn't change on lists where you're navigating.
From my experience with android, there's no 'selector' background on WP7. If you're looking for a cool UI effect that shows some action is happening, the TiltEffect is definitely recommended, and very easy to implement.
http://www.windowsphonegeek.com/articles/Silverlight-for-WP7-Toolkit-TiltEffect-in-depth
However - if you're creating an app that doesn't have immediate navigation, it is possible that you might want a 'selected' cell color / etc. I've attached an image:
https://skydrive.live.com/redir.aspx?cid=ef08824b672fb5d8&resid=EF08824B672FB5D8!366&parid=EF08824B672FB5D8!343
If you note here, the buttons are related to the selected item on the list - I.e. the user can perform 4 different actions based on the selected item, (but they must select an item first!).
internal void SelectionChanged()
{
var item = (((ListBoxItem) _view.servers.SelectedItem).Content) as StackPanel;
if (item != null)
{
for (int i = 0; i < _view.servers.Items.Count; i++)
{
var val = (((ListBoxItem) _view.servers.Items[i]).Content) as StackPanel;
var tb = val.Children[0] as TextBlock;
var tb2 = val.Children[1] as TextBlock;
if (i == _view.servers.SelectedIndex)
{
tb.Foreground = tb2.Foreground = (SolidColorBrush) App.Current.Resources["PhoneAccentBrush"];
}
else
{
tb.Foreground = tb2.Foreground = (SolidColorBrush) //regular color here, b/c all these should no longer be selected
}
}
}
}
The ListItemContainer will have it's Foreground changed automatically. To inherit this, simply don't specify a colour (or style) on your TextBlock.

how to add message map to dynamic menu item in MFC

I writing a MFC which has a listview control. When the user right clicks any item , I am generating a dynamic menu item with that text that is selected in listview. Everything is displaying properly, but I do not know how to add a message map to that dynamic menu item.
Any help?
void CMyListDlg::OnRclickList(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
int nIndex = m_List.GetSelectionMark();
CString pString = m_List.GetItemText(nIndex,1);
CMenu menu, * pSubMenu;
int pos=0;
menu.LoadMenu(IDR_MENU1);
pSubMenu = menu.GetSubMenu (0);
pSubMenu->DeleteMenu(0,MF_BYPOSITION);
pSubMenu->InsertMenu(pos,MF_BYPOSITION,NULL,pString);
CPoint oPoint;
GetCursorPos (& oPoint);
pSubMenu-> TrackPopupMenu (TPM_LEFTALIGN, oPoint.x, oPoint.y, this);
*pResult = 0;
}
At the moment you are inserting the menu item with ID = 0 (NULL). That way you can't figure out which command was pressed. You have to assign an ID to the item, the simplest one is to
#define WM_MYMESSAGE WM_USER + 1
then you insert it like this:
pSubMenu->InsertMenu(pos,MF_BYPOSITION,WM_MYMESSAGE,pString);
If you override OnCommand for your window, you get your ID as wParam.
To actually figure out what happened, store some additional information in another class member, like m_nLastItemClicked or ... you get the idea?!
Check the MFCIE sample, it generates a favorite menu from the user's favorite folder and navigates to the favorite url when a favorite menu item is clicked.
Just add ON_COMMAND (and ON_UPDATE_COMMAND_UI if necessary) handlers for the menu items' IDs on your class.

Resources