Click here to Skip to main content
15,867,568 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
i am creating desktop applicaton so when i am try to resize window of winform then all controls are resize at runtime. i am also try C# and VB.net code in project but it does not work...

What I have tried:

#include <string>
#include <unordered_map>
#include <stdexcept>
#include <any>
#include "floating_point_to_integer.h"


namespace Rect { class Resizer; }

//Main_Form

namespace Rect
{

class Form1 : public System::Windows::Forms::Form
{

private:
Resizer *rs = new Resizer();

public:
virtual ~Form1()
{
delete rs;
}

Form1()
{
InitializeComponent();


}

private:
void Form1_Resize(std::any sender, EventArgs *e)
{
rs->ResizeAllControls(this);
}

void Form1_Load(std::any sender, EventArgs *e)
{
rs->FindAllControls(this);
}


};
}


//class Resizer

namespace Rect
{
class Resizer
{
private:
class ControlInfo
{
public:
std::wstring name;
std::wstring parentName;
double leftOffsetPercent = 0;
double topOffsetPercent = 0;
double heightPercent = 0;
int originalHeight = 0;
int originalWidth = 0;
double widthPercent = 0;
float originalFontSize = 0;
};

private:
std::unordered_map<std::wstring, controlinfo=""> ctrlDict = std::unordered_map<std::wstring, controlinfo="">();

public:
void FindAllControls(System::Windows::Forms::Control *thisCtrl)
{

// -- If the current control has a parent, store all original relative position
// -- and size information in the dictionary.
// -- Recursively call FindAllControls for each control contained in the
// -- current Control
for (auto ctl : *thisCtrl->Controls)
{
try
{
if (ctl->Parent != nullptr)
{
auto parentHeight = ctl->Parent->Height;
auto parentWidth = ctl->Parent->Width;
auto c = ControlInfo();
c.name = ctl->Name;
c.parentName = ctl->Parent->Name;
c.topOffsetPercent = static_cast<double>(ctl->Top) / static_cast<double>(parentHeight);
c.leftOffsetPercent = static_cast<double>(ctl->Left) / static_cast<double>(parentWidth);
c.heightPercent = static_cast<double>(ctl->Height) / static_cast<double>(parentHeight);
c.widthPercent = static_cast<double>(ctl->Width) / static_cast<double>(parentWidth);
c.originalFontSize = ctl->Font->Size;
c.originalHeight = ctl->Height;
c.originalWidth = ctl->Width;
ctrlDict.emplace(c.name, c);
}
}
catch (const std::runtime_error &ex)
{
Debug::Print(ex.what());
}

if (ctl->Controls->Count > 0)
{
FindAllControls(ctl);
}
} // -- For Each
}
void ResizeAllControls(System::Windows::Forms::Control *thisCtrl)
{
float fontRatioW;
float fontRatioH;
float fontRatio;
System::Drawing::Font *f;

// -- Resize and reposition all controls in the passed control
for (auto ctl : *thisCtrl->Controls)
{
try
{
if (ctl->Parent != nullptr)
{
auto parentHeight = ctl->Parent->Height;
auto parentWidth = ctl->Parent->Width;
auto c = ControlInfo();
bool ret = false;
try
{
// -- Get the current control's info from the control info dictionary
std::unordered_map<std::wstring, controlinfo="">::const_iterator ctrlDict_iterator = ctrlDict.find(ctl.Name);
ret = ctrlDict_iterator != ctrlDict.end();
c = ctrlDict_iterator->second;

// -- If found, adjust the current control based on control relative
// -- size and position information stored in the dictionary
if (ret)
{
// -- Size
ctl->Width = FloatingPointToInteger::ToInt32(parentWidth * c.widthPercent);
ctl->Height = FloatingPointToInteger::ToInt32(parentHeight * c.heightPercent);

// -- Position
ctl->Top = FloatingPointToInteger::ToInt32(parentHeight * c.topOffsetPercent);
ctl->Left = FloatingPointToInteger::ToInt32(parentWidth * c.leftOffsetPercent);

// -- Font
f = ctl->Font;
fontRatioW = ctl->Width / c.originalWidth;
fontRatioH = ctl->Height / c.originalHeight;
fontRatio = (fontRatioW + fontRatioH) / 2; // -- average change in control Height and Width
ctl->Font = new Font(f->FontFamily, c.originalFontSize * fontRatio, f->Style);
}
}
catch (...)
{
}
}
}
catch (const std::runtime_error &ex)
{
}

// -- Recursive call for controls contained in the current control
if (ctl->Controls->Count > 0)
{
ResizeAllControls(ctl);
}
} // -- For Each
}
};
}
Posted
Updated 21-Mar-20 12:49pm
Comments
gggustafson 21-Mar-20 18:15pm    
can't you just dock and anchor

1 solution

Don't even think about it.
It's complicated: a lot more so than you think: especially when you try to work with font sizes changing to fit text into resized controls. Think about it: font sizes are pretty much discrete values, which controls can grow and shrink by a pixel at a time. And font size is only usable when it is readable by the human sitting looking at it, and your code has no idea what is "readable", nor can it be defined as a "generic value". Add in that the font size is not just a function of the control size, but of the amount of data in the control - and many, many controls can contain a run-time determined amount of data - and the calculations not only become very complex, but also require a good deal of iteration and still probably won't result in a comfortable and readable form - let alone a "good looking" one - especially as the number of controls on a form increases.

Instead, look at your whole UI design, and design that so that it work well regardless of resolution - the VS layout of a central text area surrounded by dockable "boxes" works well for example, but may not fit your application.

There is no "one solution" which will work for all apps at all resolutions!
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900