LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

pixel perfect sizing and relocation

Solved!
Go to solution

I'm trying to refine a library I've made for looking up (and setting) panel locations and sizes.  I've got some bug somewhere in my frame thickness lookup, as it's returning a value of 8, whereas in my UIR, the default value is 3.  I can't find the discrepancy of 5 pixels (assuming it's a Windows 10 theming issue?).

 

My lookup function:

Rect GetPanelBounds(int panel)
{
	Rect bounds = {0};
	int measurement;
	
	// look up the panel location
	GetPanelAttribute(panel, ATTR_LEFT,		&bounds.left);
	GetPanelAttribute(panel, ATTR_TOP, 		&bounds.top);
	
	// look up the panel size
	GetPanelAttribute(panel, ATTR_HEIGHT, 	&bounds.height);
	GetPanelAttribute(panel, ATTR_WIDTH, 	&bounds.width);
	
	// for information only
	GetPanelAttribute(panel, ATTR_MENU_HEIGHT, &measurement);
	
	// add the frame borders to width
	GetPanelAttribute(panel, ATTR_FRAME_ACTUAL_WIDTH, &measurement);
	bounds.width += (2 * measurement);
	
	// remove a frame border from left location
	bounds.left -= (1 * measurement);
	
	// add the frame borders to height (includes menu)
	GetPanelAttribute(panel, ATTR_FRAME_ACTUAL_HEIGHT, &measurement);
	bounds.height += (2 * measurement);

	// remove a frame border from top location
	bounds.top -= (1 * measurement);
	
	// add the titlebar to height
	GetPanelAttribute(panel, ATTR_TITLEBAR_ACTUAL_THICKNESS, &measurement);
	bounds.height += measurement;

	// remove a titlebar from top location
	bounds.top -= measurement;
	
	return bounds;
}

 

And my setter function:

 

void SetPanelBounds(int panel, Rect bounds)
{
	int measurement;
	
	// remove the frame borders from width
	GetPanelAttribute(panel, ATTR_FRAME_ACTUAL_WIDTH, &measurement);
	bounds.width -= (2 * measurement);
	
	// add a frame border to left location
	bounds.left += (1 * measurement);
	
	// remove the frame borders from height (includes menu)
	GetPanelAttribute(panel, ATTR_TITLEBAR_THICKNESS, &measurement);
	GetPanelAttribute(panel, ATTR_FRAME_ACTUAL_HEIGHT, &measurement);
	bounds.height -= (2 * measurement);
	
	// add a frame border to top location
	bounds.top += (1 * measurement);
	
	// remove the titlebar from height
	GetPanelAttribute(panel, ATTR_TITLEBAR_ACTUAL_THICKNESS, &measurement);
	bounds.height -= measurement;

	// remove a titlebar from top location
	bounds.top += measurement;
	
	// apply the panel size
	SetPanelAttribute(panel, ATTR_HEIGHT, 	bounds.height);
	SetPanelAttribute(panel, ATTR_WIDTH, 	bounds.width);
	
	// set location
	SetPanelAttribute(panel, ATTR_LEFT,		bounds.left);
	SetPanelAttribute(panel, ATTR_TOP, 		bounds.top);
}
0 Kudos
Message 1 of 2
(2,644 Views)
Solution
Accepted by topic author ElectroLund

Wow, I sure made that overly complicated.  After reading more in the SW manual, I see that ATTR_TOP and ATTR_LEFT for panels are relative to the panel excluding the titlebar.  Therefore, it's much simpler to completely disregard all other dimensions when Getting and Setting.

 

So a new set of functions looks like this and I get good pixel-perfect results:

 

Rect GetPanelBounds(int panel)
{
	Rect bounds = {0};
	
	GetPanelAttribute(panel, ATTR_HEIGHT,	&bounds.height);
	GetPanelAttribute(panel, ATTR_WIDTH,	&bounds.width);
	GetPanelAttribute(panel, ATTR_LEFT,		&bounds.left);
	GetPanelAttribute(panel, ATTR_TOP, 		&bounds.top);

	return bounds;
}

void SetPanelBounds(int panel, Rect bounds)
{
	SetPanelSize(panel, bounds.height, bounds.width);
	SetPanelPos(panel, bounds.top, bounds.left);
}

 

0 Kudos
Message 2 of 2
(2,621 Views)