Advanced MFC Programming

Advanced MFC Programming Advanced MFC Programming

math.hcmuns.edu.vn
from math.hcmuns.edu.vn More from this publisher
11.04.2014 Views

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

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!