Re: button creation
first of all, thank you very much for your support. It is also my
first programm in MFC and with C++.
is it much better to create all the buttons from a view in the
OnInitialUpdate() method instead of placing the buttons with the
resource editor....
****
No. In fact, the simplest categorization is that is always and forever a =
MISTAKE to try to
do this. The truth is more complex than that, but this simple guidelin=
e will serve you
well.
*****
Ok, I hope I got you right: You should install all button items and so
on in the resource-editor (dialog-box) and add all specific code (like
images for the buttons) in the OnInitialUpdate() and OnUpdate()
method. That means if I use more than one language I will use the
function LoadString() in the OnUpdate() method in each view to load
the correct text string to each specific item in the current dialog
box.
But how will I get the specific ID (of each item from the dialogbox)
in the view-class to add additional things like images, textstrings?
m_btnMenu1Ok.SetButtonImg(IDB_BTN_IMG_OK, IDB_BTN_IMG_OK_PRESSED);
m_btnMenu1Ok.SubclassDlgItem(IDC_MENU1_BTN_BACK_OK, this);
With this line, the Cbutton object m_btnMenu1Ok will be connected to
the cbutton, drawn in the dialog with this id
(IDC_MENU1_BTN_BACK_OK)....
Ok I think I found the correct function for that: if it is also
working in a sdi app.
void CApplicationDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, lblExample, m_lblExample);
}
After that: add a string from the string-table:
m_lblExample.SetWindowText(m_pLanguage-
GetString(IDS_EXAMPLE).c_str());
****
Why do you think white makes sense here? Why did you not use
::GetSysColor(COLOR_WINDOW)
for the color? Either follow the user's color scheme, or don't do ANYT=
HING!
****>m_btnMenu1Ok.SetColor(CImageTextButton::BTNST_COLOR_FG_OUT, RGB(150,
150, 150));
****
What could 150, 150, 150 POSSIBLY mean? Did you not mean
::GetSysColor(COLOR_BTNFACE)
?
FOLLOW THE USER'S COLOR SCHEME!
****>m_btnMenu1Ok.SubclassDlgItem(IDC_MENU1_BTN_BACK_OK, this);
****
You are in such deep trouble here. Why in the world would you Subclass=
DlgItem? If you
are calling this, you are not using MFC correctly! Even if you create =
buttons
dynamically, you would not need to do this!
*****
I`ve read in the www that SubclassDlgItem() is not a safe method - is
this statement true? Maybe someone of you could give me some more
information about this statement to improve me knowledge...
*****
It is an indication that you have no idea how to use MFC correctly. So=
if you need to do
it, re-examine what you are doing! When I was clueless about MFC, I on=
ce wrote it (some
time in my first or second MFC program) and was given similar advice.
There is no need to use it. So don't.
*****
As you pointed it out - I`m very new to c++ and to mfc: But I`ll learn
this language - and therefore it would be great if you could point it
out why this function (SubclassDlgItem()) is useless? Is it a unsafe
method? Or is it a global function?
Version2: create the whole button in the OnInitialUpdate() method
m_btnMenu1Ok.Create("OK", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
CRect(10, 10, 30, 30), this, 1);
****
First the CRect is a colossal blunder. Where in the world did you get =
the idea that
10,10,30,30 could possibly make sense? Sure, on YOUR machine, with YOU=
R display, YOUR
graphics card, YOUR current version of the display driver, YOUR current r=
esolution, and
YOUR default font size, but unless the program is now and forever going t=
o run on YOUR
machine and you will never, ever change any one of these settings or comp=
onents, it cannot
possibly run correctly anywhere else. So don't do it.
Thanks for the hint - I didn`t recoginze it.... And 10,10,30,30 was
only a example....
In situations where I have to create buttons dynamically (because the num=
ber of buttons is
based on some only-known-at-run-time set of parameters) I will always cre=
ate an
*invisible* button on the dialog, and use it to get the necessary paramet=
ers, e.g.,
CRect r;
c_ButtonPrototype.GetWindowRect(&r);
ScreenToClient(&r);
This will give me the width and height I need; for positioning, I usually=
place some
control on the dialog I can use as a reference point (sometimes an invisi=
ble CStatic) and
use it to determine the top and left of an array of buttons. I usually=
separate them by
some platform-independent computation, like 3 * ::GetSystemMetrics(SM_CXE=
DGE) or 3 *
::GetSystemMetrics(SM_CYEDGE) or some similar computation that will work =
on every screen,
every resolution, etc..
Assume that ANY hardwired integer you use for computing position, unless =
it is a simple
multiplier or divisor of a runtime-determined value, is erroneous.
For example, to center a button, I will use
CRect r;
GetClientRect(&r);
CRect b;
c_OK.GetWindowRect(&b);
ScreenToClient(&b);
c_OK.SetWindowPos(NULL, r.Width() / 2 - b.Width() / 2,
r=
..Height() / 2 - b.Height() / 2,
0=
, 0,
S=
WP_NOZORDER | SWP_NOSIZE);
and this will put the button dead center in the dialog. But if you EVE=
R choose an
absolute coordinate or size, you are DEAD WRONG. This includes font si=
zes.
What is "1" for a control ID? Did you not mean IDOK? And what is En=
glish-language text,
and 8-bit text at that, doing in a source program?
OK, a new record. There are FOUR things wrong with the above line, not=
the least of which
is its very existence!
*****>m_btnMenu1Ok.SetButtonImg(IDB_BTN_IMG_OK, IDB_BTN_IMG_OK_PRESSED);
m_btnMenu1Ok.SetFont("Arial",16);
****
You should not be deciding either the font or its size! Why do you thi=
nk Arial 16 could
possibly make sense? Because it sort-of-looks-like what you are seeing=
? In exactly which
version of Windows? (Did you know that Microsoft has changed the defau=
lt dialog font
appearance in every recent version of Windows? You should not presume =
your dialog is
going to run on the same version of the operating system, including servi=
ce pack, that you
are using!)
When you create a dialog control explicitly, the best way to set the font=
is
CFont * f = GetFont();
ctl.SetFont(f);
which uses the same font as the dialog, and this font will track OS versi=
ons and user
preferences. It will look like all the other dialogs the user has, and=
its size will
track properly.
*****>m_btnMenu1Ok.SetColor(CImageTextButton::BTNST_COLOR_FG_IN, RGB(255,
255, 255));
m_btnMenu1Ok.SetColor(CImageTextButton::BTNST_COLOR_FG_OUT, RGB(150,
150, 150));
best regards
Hans