|
|
when create a dialog based MFC project defaultly, we have the OK, cancel buttons in the topright corner, I want to create a CListBox dynamicly and place it in the position relative to the IDOK button( the top cordination of CListBox is the same as IDOK), so I write my code like below:
first, construct a CListBox in the .h file
CListBox m_ctlBox;
then, within the OnInitDialog
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_ctlBox.Create(STYLE, CRect(0, 0, 0, 0), rightcode);
m_ctlBox.ShowWindow(SW_HIDE);
CRect rcOK;
GetDlgItem(IDOK)->GetWindowRect(&rcOK);
int nBoxWidth = 30;
int nBoxHeight = 40;
int nxMargin = 10;
int nBoxTop = rcOK.top;
int nBoxLeft = rcOK.left - nxMargin - nBoxWidth;
m_ctlBox.SetWindowPos(&CWnd::wndTop, nBoxLeft, nBoxTop, nBoxWidth, nBoxHeight, SWP_SHOWWINDOW);
m_ctlBox.ShowWindow(SW_SHOW);
return TRUE;
}
but the m_ctlBox's top is not as IDOK's. Really confused with how to use GetClientRect 、GetWindowRect、ScreenToClient and ClientToScreen correctly to set window position correctly.
So I can't write my code to deal with WM_SIZE correctly.
|
|
|
|
|
GetWindowRect() gets coords relative to the screen.
SetWindowPos() is expecting coords relative to the parents client area.
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_ctlBox.Create(STYLE, CRect(0, 0, 0, 0), <font color="Red">this</font>);
m_ctlBox.ShowWindow(SW_HIDE); <font color="Green">
CRect rcOK;
GetDlgItem(IDOK)->GetWindowRect(&rcOK);
int nBoxWidth = 30;
int nBoxHeight = 40;
int nxMargin = 10;
<font color="Red"> CPoint BoxUpperLeft;
BoxUpperLeft.y = rcOK.top;
BoxUpperLeft.x = rcOK.left - nxMargin - nBoxWidth;
ScreenToClient(&BoxUpperLeft); <font color="Green">
</font> m_ctlBox.SetWindowPos(&CWnd::wndTop, <font color="Red">BoxUpperLeft.x</font>, <font color="Red">BoxUpperLeft.y</font>, nBoxWidth, nBoxHeight, SWP_SHOWWINDOW);
m_ctlBox.ShowWindow(SW_SHOW);
return TRUE;
} Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Question NO.1
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_ctlBox.Create(STYLE, CRect(0, 0, 0, 0),this);
m_ctlBox.ShowWindow(SW_HIDE);
CRect rcOK;
GetDlgItem(IDOK)-><big><font color="red">GetWindowRect</font></big>(&rcOK);
int nBoxWidth = 30;
int nBoxHeight = 40;
int nxMargin = 10;
CPoint BoxUpperLeft;
BoxUpperLeft.y = rcOK.top;
BoxUpperLeft.x = rcOK.left - nxMargin - nBoxWidth;
<big>this->ScreenToClient(&BoxUpperLeft)</big>
<font color=blue>
</font>
m_ctlBox.SetWindowPos(&CWnd::wndTop, BoxUpperLeft.x, BoxUpperLeft.y, nBoxWidth, nBoxHeight, SWP_SHOWWINDOW);
m_ctlBox.ShowWindow(SW_SHOW);
return TRUE;
}
Question NO.2
and how to do it with GetClientRect()?
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_ctlBox.Create(STYLE, CRect(0, 0, 0, 0),this);
m_ctlBox.ShowWindow(SW_HIDE);
CRect rcOK;
GetDlgItem(IDOK)-><big><font color="red">GetClientRect</font></big>(&rcOK);
int nBoxWidth = 30;
int nBoxHeight = 40;
int nxMargin = 10;
CPoint BoxUpperLeft;
BoxUpperLeft.y = rcOK.top;
BoxUpperLeft.x = rcOK.left - nxMargin - nBoxWidth;
m_ctlBox.SetWindowPos(&CWnd::wndTop, BoxUpperLeft.x, BoxUpperLeft.y, nBoxWidth, nBoxHeight, SWP_SHOWWINDOW);
m_ctlBox.ShowWindow(SW_SHOW);
return TRUE;
}
-- modified at 2:40 Wednesday 21st November, 2007
|
|
|
|
|
Before going into your question,
GetWindowRect(..) will return the window rect with respect to screen cooridates.
GetClientRect(..) will return the client area of the window, that is regardless of its position the top left point is 0, 0 and right, bottom point is its width and height respectivly
Now for Question 1:
You got the screen coordinate of OK button, now you have to find its coordinate with respect to the dialog and not with the listbox.
For Question 2:
As i said earlier, if you use GetClientRect(..), simply it will return width and height. By knowing only the width and height you can't find its starting (top,left) coordinate.
Do your Duty and Don't expect the Result
|
|
|
|
|
When I see the explaination of the API ::ScreenToClient(), I understand clearly.
GetDlgItem(IDOK)->GetWindowRect(&rcOK);
First, rcOK's coordinates are relative to the upper left of the display screen.
Then compulate the position of the CListBox to the coordinates relative to display screen.
Next we need convert the screen coordinates of the CListBox to the coordinates in the main Dialog's client coordinates.
<br />
BOOL ScreenToClient(<br />
HWND hWnd,
LPPOINT lpPoint
);<br />
hWnd <br />
[in] Handle to the window <big><font color="red">whose client area will be used </font></big> for the conversion.
so we should pass the dialog's hWnd.
BOOL CMyDialog::OnInitDialog()
{
CDialog::OnInitDialog();
m_ctlBox.Create(STYLE, CRect(0, 0, 0, 0),this);
m_ctlBox.ShowWindow(SW_HIDE);
CRect rcOK;
GetDlgItem(IDOK)->GetWindowRect(&rcOK);
int nBoxWidth = 30;
int nBoxHeight = 40;
int nxMargin = 10;
CPoint BoxUpperLeft;
BoxUpperLeft.y = rcOK.top;
BoxUpperLeft.x = rcOK.left - nxMargin - nBoxWidth;
::ScreenToClient(this->m_hWnd, &BoxUpperLeft);
<font color="red">
m_ctlBox.SetWindowPos(&CWnd::wndTop, BoxUpperLeft.x, BoxUpperLeft.y, nBoxWidth, nBoxHeight, SWP_SHOWWINDOW);
m_ctlBox.ShowWindow(SW_SHOW);
return TRUE;
}
If somewhere is wrong, please correct me! thx.
-- modified at 0:17 Thursday 22nd November, 2007
|
|
|
|
|
There's not an API (or CWnd method) I know of to get the rect of a window relative
to its parent, so your GetClientRect() method isn't going to give you the info you need.
Remember, the window rect is the outer bounding rect of the window. The client rect
is the interior of the window, excluding borders, title bar, menu, and other "decorations".
As Parthi mentioned, the client rect's upper left coord is always 0,0.
Controls are windows, so the same rules apply.
About Windows[^]
MapWindowPoints()[^]
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
<br />
class CMyEdit:public CEdit<br />
<br />
void CMyEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)<br />
{<br />
CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
CString s;<br />
GetWindowText(s);
}<br />
I want to use the WindowText as soon as the text is changed, any way?
Thanks.
|
|
|
|
|
Why you dont use of EN_CHANGE ?
|
|
|
|
|
|
did you try handling the EN_CHANGE message?
|
|
|
|
|
|
in the cpp file write
BEGIN_MESSAGE_MAP(CYourEdit, CEdit)
ON_NOTIFY_REFLECT(EN_CHANGE, OnEnChange)
END_MESSAGE_MAP()
afx_msg void OnEnChange(NMHDR *pNMHDR , LRESULT *pResult);
void CYourEdit::OnEnChange(NMHDR *pNMHDR , LRESULT *pResult)
{
CEdit::GetWindowText(str);
//Then use the str to do your work
}
|
|
|
|
|
hi how to convert tchar to const char
paulraj
|
|
|
|
|
It will not be perfect, because tchar may have 2 bytes or 1 byte,
you can't put 2 byte into 1 byte when converting,
however it may work when tchar takes 1 byte. All depends on your code, you can try it.
<br />
TCHAR t;<br />
const char c=char(t);<br />
or
<br />
TCHAR t;<br />
const char *pc=cosnt char*(&t);<br />
|
|
|
|
|
followait wrote: tchar may have 2 bytes or 1 byte
when TCHAR takes 2 bytes ?
Thanks
|
|
|
|
|
TCHAR is a macro that resolves either to char if UNICODE is not defined (then it will be 1 byte) or to wchar if UNICODE is defined (then it will be 2 bytes).
|
|
|
|
|
TCHAR t;
const char *pc=cosnt char*(&t);
hi... i used this way.
but i didn't get the answer.
the error is "syntax error:'const'
my input is TCHAR[500];
i have to change this in const char* format. can you help me?
paulraj
|
|
|
|
|
I'm looking for some sample code to see how to build an custom IE toolbar extension. I'm working on a pet project to allow an IE toolbar to interact with form data similar to how the google toolbar works. I've tried searching code project using these terms: "ie addin" "ie toolbar" "addin" but I haven't seen anything yet. Your help is appreciated.
|
|
|
|
|
|
|
That's excellent. Thank-you for pointing me in the right direction!
|
|
|
|
|
|
Thank-you for the links! I'm digging into it now.
|
|
|
|
|
I gald it was helpful for you.
|
|
|
|
|