|
I had wanted to customize the tree control by adding a header. I wanted to do the same thing the list view control does and simply add the header as a child of the tree wnd at the top of it's client rect. I got this to work OK, but when it paints it of course covers the first item of the tree ctrl. No problem I thought, I'll just override the WM_PAINT and use SetViewportOrgEx and shift the HDC's y origin up by the height of the header. That seemed to work OK. But when I clicked on an item, things would not get drawn correctly. It's as if it got shifted down too much or copied from the wrong point. If a full repaint occured then things looked OK, but if a the paint rect for the WM_PAINT was a partial, then there seemed to be nothing I could do to get it to paint correctly.
I overrode the CUSTOM_DRAW callback and verified that the correct items were getting processed. They just don't seem to show up where you would expect them. What am I missing?
Here's the default tree with one item and one child item underneath it:
pic1.PNG[^]
Now if you click on the + to open it up:
pic2.PNG[^] - obviously that's not right! the partial update doesn't seem to get handled correctly.
If you resize the window:
http://www.vcf-online.org/tmp/pic3.PNG[^]
After some experimenting, the problem seems to revolve around the use of the SetViewportOrgEx call. If that is not called, the first item will not show, but the updates will be processed correctly (for example, if you add more items to the tree and try opening/closing them). But if you then adjust the origin with SetViewportOrgEx then the painting gets screwed up.
Note: I have NOT solved this problem - at the moment I'm completely stumped as to why it doesn't work right and what I can do to fix it.
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
SELECT * FROM User WHERE Clue > 0
0 rows returned
Save an Orange - Use the VCF!
VCF Blog
modified on Monday, April 14, 2008 11:16 AM
|
|
|
|
|
Glad to hear you solved the problem. I'll have to keep this approach in mind in the future.
An alternative that I use myself, is to just handle the WM_NCCALCSIZE & WM_NCPAINT messages. For example
LRESULT CLeftView::OnNcCalcSize(WPARAM wParam, LPARAM lParam)
{
RECT *prect = (RECT *)lParam;
WndProcDefault(GetHwnd(), WM_NCCALCSIZE, wParam, lParam);
m_ncRect.left = prect->left;
m_ncRect.right = prect->right;
m_ncRect.top = prect->top;
m_ncRect.bottom = prect->top + 22;
prect->top += 24;
SCROLLBARINFO sbi;
::ZeroMemory(&sbi, sizeof(SCROLLBARINFO));
sbi.cbSize = sizeof(sbi);
if (::GetScrollBarInfo(GetHwnd(), OBJID_VSCROLL, &sbi))
if (!(sbi.rgstate[0] & STATE_SYSTEM_INVISIBLE))
m_ncRect.right += ::GetSystemMetrics(SM_CXVSCROLL);
return 0L;
}
and
LRESULT CLeftView::OnNcPaint(WPARAM wParam, LPARAM lParam)
{
WndProcDefault(GetHwnd(), WM_NCPAINT, wParam, lParam);
HDC hDC = ::GetWindowDC(GetHwnd());
RECT rc;
rc.left = m_ncRect.left;
rc.right = m_ncRect.right;
rc.top = m_ncRect.bottom;
rc.bottom = m_ncRect.bottom + 2;
HBRUSH hBrush = ::CreateSolidBrush(RGB(248, 249, 252));
::FillRect(hDC, &rc, hBrush);
::DeleteObject(hBrush);
if (isThemed != 0)
drawVistaTitleBar(hDC, "Item Library");
else
DrawTitleBar(hDC);
::ReleaseDC(GetHwnd(), hDC);
return 0L;
}
Thanks to WM_NCCALCSIZE's code the scroll-bars draw correctly too. http://i291.photobucket.com/albums/ll304/enhzflep/treeView.jpg[^]
|
|
|
|
|
I didn't solve the problem. That's why I posted here
I only "seem" to have narrowed the problem down to the presence or absence of a particular function call. Unfortunately I don't know how to get it to work right.
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
SELECT * FROM User WHERE Clue > 0
0 rows returned
Save an Orange - Use the VCF!
VCF Blog
|
|
|
|
|
What would be nice is if I could expand the NC area and put the header in there. But I don't think I can do that can I? Plus how would the header respond to mouse events, dragging, etc?
¡El diablo está en mis pantalones! ¡Mire, mire!
Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)!
SELECT * FROM User WHERE Clue > 0
0 rows returned
Save an Orange - Use the VCF!
VCF Blog
|
|
|
|
|
Well this code is written using win32++ as I don't have access to a mfc enabled copy of VS, but I'd (foolishly?) assume that it would work just the same in either case.
The code I posted will decrease the size(height) of the window, while increasing the size(height) of the non-client area.
The header will respond in just the same way as the non-client area for a tree control normally will. The window proc for this control only handles WM_NCCALCSIZE and WM_NCPAINT messages, passing any others to the original wind proc.
Here's what the wind proc for the class looks like in it's entirety:
LRESULT CLeftView::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_NCCALCSIZE:
return OnNcCalcSize(wParam, lParam);
case WM_NCPAINT:
return OnNcPaint(wParam, lParam);
}
return WndProcDefault(hWnd, uMsg, wParam, lParam);
}
I'm afraid I have no recollection of where I picked this trick up, though it seems to work just fine. If I've left things unexplained, or you like the class source, I'd be happy to expand on what I've said, or mail you a copy of the class.
Simon.
[EDIT: Oops, looks like I misread that first post. Sorry 'bout that Jim. I've not used the functions you mention before, I'll see if I cant come up with something that achieves this affect using them.]
modified on Monday, April 14, 2008 12:25 PM
|
|
|
|
|
Hi,
I want to find all title of windows. But the code is giving 2 errors:
code is:
<br />
void CMainFrame::TrackWindow()<br />
{<br />
HWND hwnd;<br />
LPARAM lParam = 0; <br />
<br />
while(EnumWindows((WNDENUMPROC)EnumWindowsProc,lParam))<br />
{<br />
EnumWindowsProc(hwnd,lParam);<br />
}<br />
}<br />
<br />
static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)<br />
{<br />
char text[200];<br />
GetWindowText(hwnd,text,200);<br />
AfxMessageBox(text);<br />
return TRUE;<br />
};<br />
<br />
Erros are:
1.'type cast' : cannot convert from 'overloaded-function' to 'WNDENUMPROC'
2. unable to recover from previous error(s); stopping compilation
|
|
|
|
|
1) Do you have a prototype for your callback function before the call to EnumWindows ?
2) <pet peeve> Change the name of the callback function to something other than the default. </pet peeve>
Judy
|
|
|
|
|
Thank you, Its working but I want to know the WindowPlacement using GetWindowPlacement() . The below code is returning null in WINDOWPLACEMENT variable.
<br />
static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)<br />
{<br />
char text[200];<br />
GetWindowText(hwnd,text,200);<br />
CString szWindowTitle=text;<br />
WINDOWPLACEMENT *WndPlacement=NULL;<br />
if(szWindowTitle=="My Window")<br />
{<br />
GetWindowPlacement(hwnd,WndPlacement);
szWindowTitle.Format("%d",WndPlacement->showCmd);<br />
AfxMessageBox(szWindowTitle);<br />
}<br />
<br />
return TRUE;<br />
};<br />
|
|
|
|
|
pther wrote: The below code is returning null in WINDOWPLACEMENT variable.
Well, of course it is since you initialize WndPlacement to NULL. You're not using the function correctly. You need to supply the buffer to receive the requesetd information. Try this.
WINDOWPLACEMENT WndPlacement;
if(szWindowTitle=="My Window")
{
GetWindowPlacement(hwnd,&WndPlacement);
szWindowTitle.Format("%d",WndPlacement.showCmd);
AfxMessageBox(szWindowTitle);
}
Judy
|
|
|
|
|
pther wrote: while(EnumWindows((WNDENUMPROC)EnumWindowsProc,lParam))
Why the cast?
pther wrote: EnumWindowsProc(hwnd,lParam);
Why are you calling this function directly? EnumWindows() will do that for you, hence the callback.
"Love people and use things, not love things and use people." - Unknown
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
I'm tring to set the Font and Fontsize to "MS Sans Serif" and 14, the code below does not seem to do it...what am I doing wrong? Is there an easier way to do this?
Thanks
CFont LargeFont;
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT));
lf.lfHeight = 24;
lf.lfWeight = 400;
strcpy(lf.lfFaceName, "MS Sans Serif");
GetDlgItem(IDC_STATIC5)->SetFont(&LargeFont);
|
|
|
|
|
You never initialize LargeFont.
Why don't you use CFont::CreatePointFont ?
|
|
|
|
|
As addendum to Cédric reply, please note you probably have to use
lf.lfHeight = -MulDiv(24, GetDeviceCaps(hDC, LOGPIXELSY), 72);
to obtain a 24 point sized font.
See [^].
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
|
|
|
|
|
C++NewBe wrote: CFont LargeFont;
Where is this object declared?
"Love people and use things, not love things and use people." - Unknown
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
The original Post was missing this:
VERIFY(LargeFont.CreateFontIndirect(&lf));
|
|
|
|
|
Ok, but that did not answer my question.
Is your problem solved now?
"Love people and use things, not love things and use people." - Unknown
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
This is my code....what am I missing? I thing it's the height and weight that is giving me problem. I am from VB world.
thanks
CFont LargeFont;
LOGFONT lf;
memset(&lf, 0, sizeof(LOGFONT));
lf.lfHeight = 24;
lf.lfWeight = 400;
strcpy(lf.lfFaceName, "MS Sans Serif");
VERIFY(LargeFont.CreateFontIndirect(&lf));
GetDlgItem(IDC_STATIC5)->SetFont(&LargeFont);
|
|
|
|
|
C++NewBe wrote: CFont LargeFont;
Where is this object declared? If it is not global, or is not a member of the dialog, it will go out of scope before SetFont() has a chance to work.
"Love people and use things, not love things and use people." - Unknown
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Now I understand....it is being declared on ::Paint()
|
|
|
|
|
C++NewBe wrote: it is being declared on ::Paint()
Therein lies the problem.
"Love people and use things, not love things and use people." - Unknown
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
|
|
|
|
|
Hello all,
I need checkboxes in List box.I am using Visual Studio 2003.
please suggest some solution.
Thanks & Regards,
Rahul
|
|
|
|
|
Link[^]
Nobody can give you wiser advice than yourself. - Cicero
.·´¯`·->Rajesh<-·´¯`·.
Codeproject.com: Visual C++ MVP
|
|
|
|
|
|
Rajkumar R wrote: multi-check ListBox[^] may be useful,
Had you followed my link, that's the same article I suggested too, besides indirectly telling him to use Google too.
Nobody can give you wiser advice than yourself. - Cicero
.·´¯`·->Rajesh<-·´¯`·.
Codeproject.com: Visual C++ MVP
|
|
|
|
|
|