Advanced MFC Programming
Advanced MFC Programming Advanced MFC Programming
Chapter 5. Common Controls CSpinButtonCtrl type variable for the spin control (through using Class Wizard). The following code fragment shows how the buddy of the two spin controls are set using the first method: …… BOOL CCCtlDlg::OnInitDialog() { ( (CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_VER) )->SetBuddy(GetDlgItem(IDC_EDIT_VER)); ( (CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_HOR) )->SetBuddy(GetDlgItem(IDC_EDIT_HOR)); } return TRUE; Since CWnd::GetDigItem(…) returns a CWnd type pointer, we need to first cast it to CSpinButtonCtrl type pointer in order to call any member function of class CSpinButtonCtrl. The only parameter that needs to be passed to function CSpinButtonCtrl::SetBuddy(…) is a CWnd type pointer to the buddy control, which can also be obtained by calling function CWnd::GetDlgItem(…). Spin controls implemented in sample 5.1-2\CCtl behaves exactly the same with those implemented in sample 5.1-1\CCtl. 5.2 Customizing the Properties of Spin Control We can customize a spin control’s properties in function CDialog::OnInitDialog(). The following three functions are the most commonly used ones for doing customization: Function Name Int CSpinButtonCtrl::SetBase ( int nBase ); Void CSpinButtonCtrl::SetRange ( int nLower, int nUpper ); int CSpinButtonCtrl::SetPos ( int nPos ); Description We can use this function to set the base of a spin control. Parameter nBase can be either 10 or 16, which will make the buddy window display decimal or hexadecimal numbers respectively. We can use this function to set the range of a spin control. The default range is 100 to 0, so by default the number in the edit box will be decremented when we press the upward arrow of a vertical spin. To change this feature, we can call function CSpinButtonCtrl::SetRange(…) to set its range to be from 0 to 100 (nLower=0, nUpper=100). We can call this function to set the initial position of a spin control. If we do not set it, the default position is 0. Sample 5.2\CCtl is based on sample 5.1-1\CCtl. In this sample, the vertical spin is customized to display hexadecimal integers, whose range is set from 0x0 to 0xC8 (0 to 200), and its initial position is set to 0x64 (100). The horizontal spin still displays decimal integers, its range is from 50 to 0, and the initial position is 25. The following portion of function CCCtlDlg::OnInitDialog() shows the newly added code: …… BOOL CCCtlDlg::OnInitDialog() { ( (CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_VER) )->SetBuddy(GetDlgItem(IDC_EDIT_VER)); ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_VER))->SetRange(0, 200); ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_VER))->SetBase(16); ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_VER))->SetPos(100); ( (CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_HOR) )->SetBuddy(GetDlgItem(IDC_EDIT_HOR)); 94
Chapter 5. Common Controls ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_HOR))->SetRange(50, 0); ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_HOR))->SetBase(10); ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_HOR))->SetPos(25); } return TRUE; 5.3 Displaying Text Strings in the Buddy Window Sometimes we want the buddy to display text strings rather than numerical numbers. For example, we may prefer the text displayed in the buddy window to be “One”, “Two”, “Three”… rather than “1”, “2”, “3”…. To customize this style, we could not use “Set buddy integer” style anymore. Instead, we need to write our own message handlers and set the buddy control’s text by ourselves. When the position of a spin has changed, the parent window of the spin control will receive a UDN_DELTAPOS message. From this message, we can get the current position of the spin control, along with the proposed change to the current position. Based on this information, we can decide what we should display in the buddy control window. Sample 5.3\CCtl demonstrates how to display text strings in a buddy window. It is based on sample 5.2\CCtl, with a new spin control IDC_SPIN_STR and an edit box IDC_EDIT_STR added to the application. The edit control will display text strings “Zero”, “One”, “Two”,…, “Nine” instead of integers. The buddy of spin IDC_SPIN_STR is set automatically. The UDN_DELTAPOS message handler can be added through following steps: 1) Invoke Class Wizard, click “Messages Maps” tab. 2) Select “CCCtlDlg” class from “Class name” window, then highlight “IDC_SPIN_STR” in “Object IDs” window. 3) There will be two messages contained in “Messages” window, we need to highlight “UDN_DELTAPOS” and press “Add function” button. The newly added function will look like follows: void CCCtlDlg::OnDeltaposSpinStr(NMHDR* pNMHDR, LRESULT* pResult) { NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR; } *pResult = 0; The first parameter here is a NMHDR type pointer. This is a structure that contains Windows notification messages. A notification message is sent to the parent window of a common control to notify the changes on that control. It is used to handle events such as mouse left button clicking, left button double clicking, mouse right button clicking, and right button double clicking performed on a common control. Many types of common controls use this message to notify the parent window. For spin control, after receiving this message, we need to cast the pointer type from NMHDR to NM_UPDOWN. Here structure MN_UPDOWN is defined as follows: typedef struct _NM_UPDOWN { nmud NMHDR hdr; // notification message header int iPos; // current position int iDelta; // proposed change in position } NM_UPDOWNW; In the structure, member iPos specifies the current position of the spin control, and iDelta indicates the proposed change on spin’s position. We can calculate the new position of the spin control by adding up these two members. The following function shows how the buddy’s text is set after receiving the message: void CCCtlDlg::OnDeltaposSpinStr(NMHDR* pNMHDR, LRESULT* pResult) { int nNewPos; char szNumber[][16]= { 95
- Page 59 and 60: Chapter 2. Menu ); UINT nPosition,
- Page 61 and 62: Chapter 2. Menu void CMenuDoc::OnEd
- Page 63 and 64: Chapter 2. Menu } In the sample, bi
- Page 65 and 66: Chapter 2. Menu Message Mapping for
- Page 67 and 68: Chapter 2. Menu We can implement bi
- Page 69 and 70: Chapter 2. Menu CDC *ptrDC; CDC dcM
- Page 71 and 72: Chapter 2. Menu Because the popup m
- Page 73 and 74: Chapter 3. Splitter Window Chapter
- Page 75 and 76: Chapter 3. Splitter Window function
- Page 77 and 78: Chapter 3. Splitter Window BOOL CSp
- Page 79 and 80: Chapter 3. Splitter Window In the a
- Page 81 and 82: Chapter 3. Splitter Window Sample S
- Page 83 and 84: Chapter 3. Splitter Window WM_LBUTT
- Page 85 and 86: Chapter 4. Button Chapter 4 Buttons
- Page 87 and 88: Chapter 4. Button Use string text a
- Page 89 and 90: Chapter 4. Button function, first t
- Page 91 and 92: Chapter 4. Button Now we can remove
- Page 93 and 94: Chapter 4. Button } ( m_bBmpCheck ?
- Page 95 and 96: Chapter 4. Button using bit-wise AN
- Page 97 and 98: Chapter 4. Button Overriding Functi
- Page 99 and 100: Chapter 4. Button …… First pBit
- Page 101 and 102: Chapter 4. Button Using Class MCBit
- Page 103 and 104: Chapter 4. Button The button’s ID
- Page 105 and 106: Chapter 4. Button However, since me
- Page 107 and 108: Chapter 4. Button Here, we use subc
- Page 109: Chapter 5. Common Controls command
- Page 113 and 114: Chapter 5. Common Controls } The in
- Page 115 and 116: Chapter 5. Common Controls …… B
- Page 117 and 118: Chapter 5. Common Controls The “S
- Page 119 and 120: Chapter 5. Common Controls button
- Page 121 and 122: Chapter 5. Common Controls In this
- Page 123 and 124: Chapter 5. Common Controls (CBN_CLO
- Page 125 and 126: Chapter 5. Common Controls compare
- Page 127 and 128: Chapter 5. Common Controls } ptrEdi
- Page 129 and 130: Chapter 5. Common Controls ……
- Page 131 and 132: Chapter 5. Common Controls void CWn
- Page 133 and 134: Chapter 5. Common Controls Five loc
- Page 135 and 136: Chapter 5. Common Controls This fun
- Page 137 and 138: Chapter 5. Common Controls After cr
- Page 139 and 140: Chapter 5. Common Controls typedef
- Page 141 and 142: Chapter 5. Common Controls Using th
- Page 143 and 144: Chapter 5. Common Controls Paramete
- Page 145 and 146: Chapter 5. Common Controls void MCT
- Page 147 and 148: Chapter 5. Common Controls modifica
- Page 149 and 150: Chapter 5. Common Controls In funct
- Page 151 and 152: Chapter 5. Common Controls Changing
- Page 153 and 154: Chapter 5. Common Controls m_tabCtr
- Page 155 and 156: Chapter 5. Common Controls Custom R
- Page 157 and 158: Chapter 6. Dialog Box Chapter 6 Dia
- Page 159 and 160: Chapter 6. Dialog Box void CMLDialo
Chapter 5. Common Controls<br />
CSpinButtonCtrl type variable for the spin control (through using Class Wizard). The following code<br />
fragment shows how the buddy of the two spin controls are set using the first method:<br />
……<br />
BOOL CCCtlDlg::OnInitDialog()<br />
{<br />
(<br />
(CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_VER)<br />
)->SetBuddy(GetDlgItem(IDC_EDIT_VER));<br />
(<br />
(CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_HOR)<br />
)->SetBuddy(GetDlgItem(IDC_EDIT_HOR));<br />
}<br />
return TRUE;<br />
Since CWnd::GetDigItem(…) returns a CWnd type pointer, we need to first cast it to CSpinButtonCtrl<br />
type pointer in order to call any member function of class CSpinButtonCtrl. The only parameter that needs<br />
to be passed to function CSpinButtonCtrl::SetBuddy(…) is a CWnd type pointer to the buddy control,<br />
which can also be obtained by calling function CWnd::GetDlgItem(…).<br />
Spin controls implemented in sample 5.1-2\CCtl behaves exactly the same with those implemented in<br />
sample 5.1-1\CCtl.<br />
5.2 Customizing the Properties of Spin Control<br />
We can customize a spin control’s properties in function CDialog::OnInitDialog(). The following<br />
three functions are the most commonly used ones for doing customization:<br />
Function Name<br />
Int CSpinButtonCtrl::SetBase<br />
(<br />
int nBase<br />
);<br />
Void CSpinButtonCtrl::SetRange<br />
(<br />
int nLower, int nUpper<br />
);<br />
int CSpinButtonCtrl::SetPos<br />
(<br />
int nPos<br />
);<br />
Description<br />
We can use this function to set the base of a spin control. Parameter<br />
nBase can be either 10 or 16, which will make the buddy window<br />
display decimal or hexadecimal numbers respectively.<br />
We can use this function to set the range of a spin control. The<br />
default range is 100 to 0, so by default the number in the edit box<br />
will be decremented when we press the upward arrow of a vertical<br />
spin. To change this feature, we can call function<br />
CSpinButtonCtrl::SetRange(…) to set its range to be from 0 to 100<br />
(nLower=0, nUpper=100).<br />
We can call this function to set the initial position of a spin control.<br />
If we do not set it, the default position is 0.<br />
Sample 5.2\CCtl is based on sample 5.1-1\CCtl. In this sample, the vertical spin is customized to<br />
display hexadecimal integers, whose range is set from 0x0 to 0xC8 (0 to 200), and its initial position is set<br />
to 0x64 (100). The horizontal spin still displays decimal integers, its range is from 50 to 0, and the initial<br />
position is 25. The following portion of function CCCtlDlg::OnInitDialog() shows the newly added code:<br />
……<br />
BOOL CCCtlDlg::OnInitDialog()<br />
{<br />
(<br />
(CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_VER)<br />
)->SetBuddy(GetDlgItem(IDC_EDIT_VER));<br />
((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_VER))->SetRange(0, 200);<br />
((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_VER))->SetBase(16);<br />
((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_VER))->SetPos(100);<br />
(<br />
(CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_HOR)<br />
)->SetBuddy(GetDlgItem(IDC_EDIT_HOR));<br />
94