Archicad C++ API
About Archicad add-on development using the C++ API.

List box header

dushyant
Enthusiast

Hi,

I found that the list box header is also set using the list-box-header-strings-resource-ID, as below:

 

 

 

 

	// set texts:
	GS::UniString	headerName;
	RSGetIndString (&headerName, LAYER_DIALOG_LIST_BOX_HEADER_STRINGS_RESID, 1, ACAPI_GetOwnResModule());
	layerList.SetHeaderItemText (layerNameTab,		headerName);

	RSGetIndString (&headerName, LAYER_DIALOG_LIST_BOX_HEADER_STRINGS_RESID, 2, ACAPI_GetOwnResModule());
	layerList.SetHeaderItemText (statusTab,			headerName);

	RSGetIndString (&headerName, LAYER_DIALOG_LIST_BOX_HEADER_STRINGS_RESID, 3, ACAPI_GetOwnResModule());
	layerList.SetHeaderItemText (filterStatusTab,	headerName);

 

 

 

 

Though it can be set directly as:

 

 

 

 

	// set texts:
	buildMatList.SetHeaderItemText (BuildingMatNameTab,	"Building Material");
	buildMatList.SetHeaderItemText (PenIndexTab,		"cutFillPen");

 

 

 

 

What is the difference between the two? Which one is used in which case? What is the reason for setting the header using the resource IDs?

 

Also, what is the acceptable value range for the List Box Header Strings Resource ID? I saw it was set to 32593 when the GDLG and DLGH were 32591 (for a dialog box). I am using a palette, so GDLG and DLGH are 32500. What should be the ID for the List Box Header Strings in this case?

 

Thanks!

 

20 REPLIES 20
Miklos Vegh
Graphisoft
Graphisoft

The result of both methods are the same. But we used to put the localised resources in different modules than the executable. This way when the localized products are prepared the executable is the same for all languages, and only the dlls containing the language dependent content is varied. If not the code should be changed for each language (or some other tricks needed), and the whole executable needs to be rebuilt with every language.

The resource IDs can have any arbitrary value in [1 .. 32767], but must be unique.

Thanks!

dushyant
Enthusiast
listBox.SetHeaderItemCount(3);

The header count can be set as above. How is it different from the following?

 

listBox.SetTabFieldCount(3);

 

 

Listbox header has two modes.

In the synchron mode the header item count and sizes are set by the Dialog Manager based upon the tab field count and sizes. Whenever tab count or a tab size canges the header will follow it. And0 tabfields will also follow the corresponding header item change automatically.

 

In the asynchron mode the header and the tabs are independent. You have to manage the header count and sizes. In this mode you can put one header item for multiple tabs, but this needs more work to manage. When something changes in the header the tabs should be set and vice versa.

Thanks a lot for clarifying both the modes.

When the synchron mode is set to 'true',  how can we set a minimum width value for each header?

The SetHeaderItemMinSize can be applied to set the min value of header items for sync and async listboxes also. But this limit effects only the mouse interaction. If a tab field size is set to a lesser value from the code then the header item size will have that value also in a synchron list since the header item sizes and tabfield sizes follow each other.

SetHeaderItemMinSize is what I needed. Thanks!

dushyant
Enthusiast

I'm trying to set the width of each column of the list box based on panel-resize:

 

 

MyPalette::PanelResized(const DG::PanelResizeEvent& ev)
{
	BeginMoveResizeItems();
	listBox.Resize(ev.GetHorizontalChange(), ev.GetVerticalChange());
        short tabWidth = listBox.GetItemWidth() / 3; 
	short posBegin = 0;
	posBegin = listBox.GetTabFieldBeginPosition(1);
	listBox.SetTabFieldBeginEndPosition(1, posBegin, posBegin + tabWidth);
	posBegin = listBox.GetTabFieldBeginPosition(2);
	listBox.SetTabFieldBeginEndPosition(2, posBegin, posBegin + tabWidth);
	posBegin = listBox.GetTabFieldBeginPosition(3);
	listBox.SetTabFieldBeginEndPosition(3, posBegin, posBegin + tabWidth);
	EndMoveResizeItems();
}

 

 

This is only changing the width of the headers (though not as expected). The tab fields remain static, even though I have the synchron mode ON. Also it's odd why the header is changing as the Tab Field position is being set.

Does the synchron work with only the mouse interaction in this case too?

 

I even tried the following, but it makes no change in the header items or tab items:

	short headerItemChangeHorz = ev.GetHorizontalChange() / 3;
	short headerItemSize = 0;
	headerItemSize = listBox.GetHeaderItemSize(1);
	listBox.SetHeaderItemSize(1, headerItemSize + headerItemChangeHorz);
	headerItemSize = listBox.GetHeaderItemSize(2);
	listBox.SetHeaderItemSize(2, headerItemSize + headerItemChangeHorz);
	headerItemSize = listBox.GetHeaderItemSize(3);
	listBox.SetHeaderItemSize(3, headerItemSize + headerItemChangeHorz);

 

Well, about the second example: you are right, the synchron works with mouse interaction only. If you want to change the layout, the tabs need to be changed. As a result headers follow them.

 

The first code needs some adjustments also. On Windows when BeginMoveResizeItems is called te controls are switched to a kind of special state in the meaning that querying their sizes and positions result false values. In this case the move/resize actions are just logged by Windows internally. All the modifications are done at once when EndMoveResizeItems is called.

 

You can do the following in PanelResized:

BeginMoveResizeItems();
<Move and resize all items here>
EndMoveResizeItems();

listItemWidth = listBox.GetItemWidth (); // It has the new value now
<Layout listbox tabs here using listItemWidth>

Its best to do the layouting in a separate function which is called in the PanelResizeExited also. Sometimes fast resizing of the dialog result in inappropriate size columns which can be avoided this way.