Prev: How to show underlined menu shortcut letters by default for a contextmenu ?
Next: panel method (from Java) in MFC
From: mfc on 21 Jun 2010 14:13 Hi, 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.... Version1: create button in resource-editor and add some additional properties in the OnInitialUpdate() method of the specific view m_btnMenu1Ok.SetButtonImg(IDB_BTN_IMG_OK, IDB_BTN_IMG_OK_PRESSED); m_btnMenu1Ok.SetButtonText("OK"); m_btnMenu1Ok.SetFont("Arial",16); m_btnMenu1Ok.SetColor(CImageTextButton::BTNST_COLOR_FG_IN, RGB(255, 255, 255)); m_btnMenu1Ok.SetColor(CImageTextButton::BTNST_COLOR_FG_OUT, RGB(150, 150, 150)); m_btnMenu1Ok.SubclassDlgItem(IDC_MENU1_BTN_BACK_OK, 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... 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); m_btnMenu1Ok.SetButtonImg(IDB_BTN_IMG_OK, IDB_BTN_IMG_OK_PRESSED); m_btnMenu1Ok.SetFont("Arial",16); 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
From: Joseph M. Newcomer on 21 Jun 2010 15:00 See below... On Mon, 21 Jun 2010 11:13:22 -0700 (PDT), mfc <mfcprog(a)googlemail.com> wrote: >Hi, > >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 guideline will serve you well. ***** > >Version1: create button in resource-editor and add some additional >properties in the OnInitialUpdate() method of the specific view > >m_btnMenu1Ok.SetButtonImg(IDB_BTN_IMG_OK, IDB_BTN_IMG_OK_PRESSED); >m_btnMenu1Ok.SetButtonText("OK"); **** What is an English-language string doing in a source program? What is an 8-bit string doing in a source program? In fact, why is the text not set in the dialog editor? Three serious design errors in a single line has to be a new record! ***** >m_btnMenu1Ok.SetFont("Arial",16); **** There is nothing right about the above line. Why 16? What makes you think this could *possibly* make sense? The default font is established as part of the user's profile selections, and you either must obey them or not do anything this dumb. Don't do it. **** >m_btnMenu1Ok.SetColor(CImageTextButton::BTNST_COLOR_FG_IN, RGB(255, >255, 255)); **** 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 ANYTHING! **** >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 SubclassDlgItem? 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 once 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. ***** > >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 YOUR display, YOUR graphics card, YOUR current version of the display driver, YOUR current resolution, and YOUR default font size, but unless the program is now and forever going to run on YOUR machine and you will never, ever change any one of these settings or components, it cannot possibly run correctly anywhere else. So don't do it. In situations where I have to create buttons dynamically (because the number of buttons is based on some only-known-at-run-time set of parameters) I will always create an *invisible* button on the dialog, and use it to get the necessary parameters, 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 invisible 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_CXEDGE) 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, SWP_NOZORDER | SWP_NOSIZE); and this will put the button dead center in the dialog. But if you EVER choose an absolute coordinate or size, you are DEAD WRONG. This includes font sizes. What is "1" for a control ID? Did you not mean IDOK? And what is English-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 think 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 default 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 service 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 versions 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)); **** As already pointed out, you must not be using hardwired colors. Essentially, EVERY line you wrote except the one to set the image has no reason to exist, and they should all be deleted. In either version. joe ***** > > >best regards >Hans Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Mihai N. on 21 Jun 2010 21:54 > m_btnMenu1Ok.SetButtonImg(IDB_BTN_IMG_OK, IDB_BTN_IMG_OK_PRESSED); > m_btnMenu1Ok.SetButtonText("OK"); > m_btnMenu1Ok.SetFont("Arial",16); > m_btnMenu1Ok.SetColor(CImageTextButton::BTNST_COLOR_FG_IN, RGB(255, > 255, 255)); > m_btnMenu1Ok.SetColor(CImageTextButton::BTNST_COLOR_FG_OUT, RGB(150, > 150, 150)); > m_btnMenu1Ok.SubclassDlgItem(IDC_MENU1_BTN_BACK_OK, this); There is absolutely no reason to do that in native Windows development. You should use the resource editor, create a dialog using WYSIWYG, and at run time load it at start usnig with with one function call, DialogBox. (or family, DialogBoxIndirect, DialogBoxIndirectParam, DialogBoxParam) -- Mihai Nita [Microsoft MVP, Visual C++] http://www.mihai-nita.net ------------------------------------------ Replace _year_ with _ to get the real email
From: mfc on 22 Jun 2010 11:05 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 guideline 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 ANYTHING! > ****>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 SubclassDlgItem? 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 once 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 YOUR display, YOUR > graphics card, YOUR current version of the display driver, YOUR current resolution, and > YOUR default font size, but unless the program is now and forever going to run on YOUR > machine and you will never, ever change any one of these settings or components, 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 number of buttons is > based on some only-known-at-run-time set of parameters) I will always create an > *invisible* button on the dialog, and use it to get the necessary parameters, 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 invisible 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_CXEDGE) 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, > SWP_NOZORDER | SWP_NOSIZE); > > and this will put the button dead center in the dialog. But if you EVER choose an > absolute coordinate or size, you are DEAD WRONG. This includes font sizes. > > What is "1" for a control ID? Did you not mean IDOK? And what is English-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 think 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 default 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 service 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 versions 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
From: Scott McPhillips [MVP] on 22 Jun 2010 11:42
"mfc" <mfcprog(a)googlemail.com> wrote in message news:c7e93683-39b7-4475-9d7d-ba3b215ff228(a)x27g2000yqb.googlegroups.com... >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? SubclassDlgItem() is used by the DDX_Control call to associate the CButton control member with the button ID. You should use the DDX_Control call because it is added for you by the wizard when you create a control member variable. Calling SubclassDlgItem() yourself is redundant, and probably would cause asserts because the button is already subclassed. -- Scott McPhillips [VC++ MVP] |