|
|
 Prize winner in Competition
"MFC/C++ Sep 2003"
Comments and Discussions
|
|
 |

|
Your code does indeed enable the display of Chinese GB2312 characters but have you seen what it does to English!!!
|
|
|
|

|
if you change m_strCaption to "LiXiaoQing"(Chinese Spell), You can see Bug
I change to following:
////////////////////////////////////////////////////////////////////////////
// 2006.04.16 17:02 Modify by LiXiaoQing to Display GB2312 char
pDC->SetTextColor(m_colTxtCaption);
nFont.CreateFontIndirect(&m_lfCaption);
pOldFont = pDC->SelectObject(&nFont);
CPoint ptDraw = pt2;
pDC->TextOut(ptDraw.x,ptDraw.y,m_strCaption);
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|

|
Hey nnnnnnnnnnnnnnnn (is that too few or too little 'n's?)
Yes, I am aware of the problem when attaching the banner to a CFrameWnd derived object that contains CControlBar type controls. The problem comes in when the control requests the available area for itself to attach into. The CFrameWnd class does not calculate the area to take the CControlBar controls into account...
I will have a look at how to get around this, however one possible solution would be to create your own CControlBar derivative that merely contains the CKCSideBannerWnd control, and attach that to the CMainFrame.
Any other ideas (from whoever might be reading this thread?)
Cheers,
Peter
www.kinkycode.com
[Glossary Manager] [AfterThought Backup Lite]
99 little bugs in the code, 99 little bugs,
Fix 1 bug, recompile....
101 little bugs in the code...
|
|
|
|

|
Using the control in dialogs requires a lot of initialisation e.g. setting texts and icon. To reduce the code needed for each dialog I wrote the following function to set up the control - perhaps it helps you using this great control:
void SetupSidebannerWnd(CWnd* pWnd, CKCSideBannerWnd* pWndBanner, UINT uiDlgID)
{
ASSERT(pWnd);
ASSERT(pWndBanner);
if (!pWnd) return;
if (!pWndBanner) return;
pWndBanner->Attach(pWnd, KCSB_ATTACH_TOP);
HICON hIcon = AfxGetApp()->LoadIcon(uiDlgID);
if (hIcon)
pWndBanner->SetIcon(hIcon);
pWndBanner->SetIconPos(KCSB_ICON_LEFT|KCSB_ICON_VCENTER);
CString strTitle(MAKEINTRESOURCE(uiDlgID));
CString strTop;
CString strSub;
AfxExtractSubString(strTop, strTitle, 0, '|');
AfxExtractSubString(strSub, strTitle, 1, '|');
pWndBanner->SetTitle(strTop);
pWndBanner->SetCaption(strSub);
}
To use it in your dialog simply add the following call to your OnInitDialog():
SetupSidebannerWnd(this, &m_wndBanner, IDD);
(assuming that m_wndBanner is the banner window).
Now add a string "Title|Caption" to your resource with the same ID as the dialog and an icon also using this ID. That's it!
Ciao,
Alex
|
|
|
|
|

|
Thanks for this nice control!
I just wanted to put it to my project (which has also a German UI) and figured out some problems with the German characters ÄÖÜäöüß and even € (EUR). It seems that CDC::GetCharWidth() return bad values for these characters. My only solution is to replace the arrWidths[] entries for äö... with the corresponding values of ao...
Do you have any better solution?
Ciao,
Alex
|
|
|
|

|
do you need a hwnd at all? if i was to make such a banner i would make a class that attaches to a certain hwnd (a dialog or whatever) and then subclasses it. next i would intercept WM_NCCALCSIZE, remember currently calculated rect (after caption and borders) and modify it to make some room for the banner. another interesting message would be WM_NCPAINT where i can use the rect from WM_NCCALCSIZE and the attached hwnd to get a window dc and paint directly. benefits: no hacks with moving controls around -- suppose the developer actually does move some controls at fixed locations. in your case he/she will need to fix the positioning code. in the proposed case only the hwnd client size will be affect and control positions on the hwnd basicly remain the same (although space is still somewhat reduced). just my $.02 worth before downloading the code ) cheers, </wqw>
|
|
|
|

|
You're absolutely right! It would be possible to implement this without an HWND the way you described. It would be interesting if you (or someone else) actually went and did this.
Take care and thanks for the input
www.kinkycode.com
[Glossary Manager] [AfterThought Backup Lite]
99 little bugs in the code, 99 little bugs,
Fix 1 bug, recompile....
101 little bugs in the code...
|
|
|
|

|
Hi everyone,
I've added the UNICODE fix that was mentioned in the thread below this one. Sorry about that! Atleast its done now. This will probably be the last update unless someone (or I) have a great idea of how to improve this control some more...
www.kinkycode.com
[Glossary Manager] [AfterThought Backup Lite]
99 little bugs in the code, 99 little bugs,
Fix 1 bug, recompile....
101 little bugs in the code...
|
|
|
|

|
I really hate to tell you this, especially since you just updated the article.... but.....
The call in the CKCSideBannerWnd constructor, to load the msimg32.dll needs to be wrapped in the _T("") macro.
// try and load the MSIMG32.LIB
if ( (m_hGradMod = LoadLibrary(_T("MSIMG32.DLL"))) )
m_pGradFill = (PFNGRADFILL) GetProcAddress(m_hGradMod, "GradientFill" );
At least *I* had to, to get my unicode build to quit whining.....
Artificial intelligence is no match for natural
stupidity.
|
|
|
|
|
|
|

|
hi,
I tried to compile the demo projet and I have execution error "can't find MSGIM32.dll".
I scanned my disk, I found MSGIM32.lib.
I use VC++ 6.0 and NT 4.0.
I'd like to link statically the MSGIM32.
Can you help me ?
|
|
|
|

|
Hey,
Ok, the first problem is that you are running NT 4.0. According to MSDN, they say the dll/lib is available on:
Windows NT/2000/XP: Included in Windows 2000 and later.
Windows 95/98/Me: Included in Windows 98 and later.
secondly, I know you've probably made a typo, but you made it twice (twece), so its actually MSIMG32. What you can do is get hold of a 98, or 2K machine, find the MSIMG32.DLL file and copy that over to your NT4 machines system(32) directory.
That should resolve the issue
Regarding the static linking question, I'm not sure of the lib is available as a static link, or if merely acts as a stub. I have a feeling the lib is merely a stub (can't be statically linked)
www.kinkycode.com
[Glossary Manager] [AfterThought Backup Lite]
99 little bugs in the code, 99 little bugs,
Fix 1 bug, recompile....
101 little bugs in the code...
|
|
|
|

|
thank you for your advice, I'm going to try.
If I found an issue on how using CKCSideBannerWnd with NT 4.0, I will post the solution.
|
|
|
|
|

|
Hi Peter & Tut8,
maybe doesent have the performance of the MSDIM32.dll gradient call function, but why don't you try a self made gradient call:
(it's only a suggestion)
[Message edited twice for mistaken code ]
void GradientFill(CDC* pDC, COLORREF clr1, COLORREF clr2, CRect rc, bool bHor = true, bool bFlip = false)
{
if (bFlip)
{
COLORREF clr = clr1;
clr1 = clr2;
clr2 = clr;
}
if (pDC->GetDeviceCaps(BITSPIXEL) > 8) {
if (bHor)
{
int nWidth = rc.Width();
for (int x=0; x<nWidth; x++)
{
CRect rcl = rc;
rcl.left += x;
rcl.right += (x + 1);
double l = (double)y / (double)nWidth;
pDC->FillSolidRect(rcl, RGB(
l * GetRValue(clr1) + (1.0 - l) * GetRValue(clr2),
l * GetGValue(clr1) + (1.0 - l) * GetGValue(clr2),
l * GetBValue(clr1) + (1.0 - l) * GetBValue(clr2) ));
}
}
else
{
int nHeight = rc.Height();
for (int y=0; y<nHeight; y++)
{
CRect rcl = rc;
rcl.top += y;
rcl.bottom += (y + 1);
double l = (double)y / (double)nHeight;
pDC->FillSolidRect(rcl, RGB(
l * GetRValue(clr1) + (1.0 - l) * GetRValue(clr2),
l * GetGValue(clr1) + (1.0 - l) * GetGValue(clr2),
l * GetBValue(clr1) + (1.0 - l) * GetBValue(clr2) ));
}
}
}
else
{
pDC->FillSolidRect(rc, clr1);
}
}
|
|
|
|

|
CodeProject should start a "code snippet" gallery. You GradientFill() code would be an ideal candidate for that space...
Chris, maybe something worth considering?
www.kinkycode.com
[Glossary Manager] [AfterThought Backup Lite]
99 little bugs in the code, 99 little bugs,
Fix 1 bug, recompile....
101 little bugs in the code...
|
|
|
|

|
hi,
I tried with your function, it works good !
I have just modified one or two parameters, and replace the line :
double l = (double)y / (double)nWidth;
by :
double l = (double)x / (double)nWidth;
Thanks a lot.
|
|
|
|

|
Hi everyone,
I've updated the control to include most of the suggestions and tips that have been so kindly communicated to me. I must admit, my favourite change is the ability to texture the control
Take care and hope you enjoy it!
www.kinkycode.com
[Glossary Manager] [AfterThought Backup Lite]
99 little bugs in the code, 99 little bugs,
Fix 1 bug, recompile....
101 little bugs in the code...
|
|
|
|

|
Nice job !
A few minor changes are necessary to make your control UNICODE compatible:
1) enclose the rest of the string literals with _T("") including the definition of KCSB_CLASSNAME
2) change the paramters to the SetTitle and SetCaption functions from const char* to LPCTSTR
3) change the variable on line 541 of the cpp file from BYTE ch; to TCHAR ch;
|
|
|
|
|

|
Thank you very much, I really need it in my projects!
Got my 5!
Because I was trying different icon sizes, I made 2 small modifications for my use that I'll like to share:
1. to load the icon directly from the resource ID I have added the member:
bool CKCSideBannerWnd::SetIcon(UINT uIcon, UINT uiIconPos)
{
HICON hIcon = (HICON)::LoadImage(
AfxGetInstanceHandle(), // app instance
MAKEINTRESOURCE(uIcon), // resource ID
IMAGE_ICON, // type of image
0,0, // desired size (0 = current)
LR_DEFAULTCOLOR); // load flags
// call the original method
return SetIcon(hIcon, uiIconPos);
}
2. to ensure the correct icon drawn size, I made a small replacement at the end of the DrawIncon call:
... DrawIcon(...)
{
...
}
pDC->DrawState(
pt,
CSize(m_bmpInfo.bmWidth, m_bmpInfo.bmHeight),
m_hIcon,
DSS_NORMAL, (HBRUSH)NULL);
}
|
|
|
|
|

|
Nice article there goes my 5.
A little issue though, can we change color of title and caption texts (without modifying your source code)? Texts became unreadable when I tried to use a dark backgroud. Also, since we are at it, will you consider bitmap backgroud?
And out of curious, why don't you just integrate WndUtil.h into KCSideBannerWnd.h so we only need to maintain 2 files instead of 3? Of course, if you are reusing WndUtil.h in multiple applications then forget about it.
Thanks.
|
|
|
|
|

|
From your article:
Personally, I have never written a control that "makes space" for itself, and the concept has grasped my imagination somewhat. I have been contemplating the idea of developing a background app/service that monitors all HWND creations and attaches a banner to all windows of say, type DIALOG. This would merely be for purposes of fun and educational value... but still a cool idea I think.
Well ... not shure about how and if it can be useful, however, an idea can be to hook the WH_CALLWNDPROC and trap the WM_INITDIALOG message.
This article can give some ideas. It is not necessary to use exactly that code. But the principle could be right.
Of course, in that article I was thinking to applications, not to "services" that do the trick to ll the windows every other would have created. But the idea is essentially the same.
Let me know. By now, get my 5 !
-E-
|
|
|
|

|
Thanks for that. Yes, I was also thinking of hooking ... but was thinking more along the lines of hooking the CBT hook. I think either will work fine. But as I said, attaching the banner to EACH and every window would merely be an exercise of fun and trying to see "if I can do it".
Thanks for the help (and the vote).
Peter
www.kinkycode.com
[Glossary Manager] [AfterThought Backup Lite]
99 little bugs in the code, 99 little bugs,
Fix 1 bug, recompile....
101 little bugs in the code...
|
|
|
|

|
Russian text output in caption in bad order. Then you get char fron string
ch = m_strCaption.GetAt(i);
if char code > 127 it appears as negative number
in void CKCSideBannerWnd::DrawTextFields(CDC* pDC, CRect rect)
replace
int ch;
with
BYTE ch;
|
|
|
|
|

|
The edit control is actually a child of the combobox (ID = 1001). The reason it is returned in your ChildEnumProc is that EnumChildWindows will enumerate all the child windows of the given window, and all the children of the child windows, for as many generations as it takes to enumerate them all. The reason it does not find the list portion of the combobox is because the list box is actually a child of the desktop.
Sonork 100.11743 Chicken Little
"You're obviously a superstar." - Christian Graus about me - 12 Feb '03
Within you lies the power for good - Use it!
|
|
|
|
|
|

|
Nice Work! it does add a nice professional look!!!
1) Add:
#pragma comment(lib, "MSIMG32.LIB")
to the file that needs it (for the Gradient Fill)
so the library gets linked, but the project settings don't have to be changed.
You could also add an optional DEFINE that would exclude
this functionality, in case people don't want to link to this library ???
2)Change the download:
a) Add example .exe file to the download
b) Delete large files that aren't needed to re-build the project (eg. the .ncb file)
to save CP bandwidth.
Warren
|
|
|
|
|

|
Great class.
Ive been looking for something similar which could be placed above a view (similar to Windows Explorer).
|
|
|
|
|

|
Youre right - it does work ! The only problem I have is that the ListCtrl and the HeaderCtrl both need to be moved down so they appear below the caption (which at the top of the CListView).
I think MoveWindow may need to be called in CListView::OnSize - ill let you know if i have any luck.
Thanks
Andy
|
|
|
|

|
Excellent idea!
SoftechSoftware
Davide Calabro'
davide_calabro@yahoo.com
http://www.softechsoftware.it
|
|
|
|

|
...to say why not use static control with a image set, but then I show some of the functions which make it a viable option over a static control.
Good!
|
|
|
|

|
One of possible usages could be displaying of some help/quick tip on dialog usage. Good color filling would be COLOR_INFOBK. This brings possible improvement - good looking button in the banner to hide it
Igor Green
Compare It! - file compare and merge tool with syntax highlighting.
|
|
|
|

|
Hi there,
Nice control, though vertical text isn't very readable. Maybe implementing the control horizontally like in many installers and apps (noticeably in Eclipse platform) should give that nifty "professional looking feel" to most windows and also providing useful information to the user.
Cheers,
Rui
is this a sig?
|
|
|
|

|
Just checked that it can be in horizontal. Maybe by default?
is this a sig?
|
|
|
|

|
I agree. Horizontal banners are more legible. However, with respect to the fact that that is merely MY opinion, and other people may enjoy the vertical banners, I decided to support all the edges of a window.
www.kinkycode.com
[Glossary Manager] [AfterThought Backup Lite]
99 little bugs in the code, 99 little bugs,
Fix 1 bug, recompile....
101 little bugs in the code...
|
|
|
|

|
After reading the article, I've found myself mentally going through all my software to think where I
can implement it.
Iain: "OOOO. New shiny thing. Must implement."
Now if it worked with Property sheet wizards...!
Go on, you know you want to. As sheer bribery, I'll reserve my voting until after you pander to me.
Congrats,
Iain.
|
|
|
|

|
*smile* Simple. Derive a class from CPropertySheet...
In your header you put the bolded line below...
#include "KCSideBannerWnd.h"
class CBannerPropSheet : public CPropertySheet
{
CKCSideBannerWnd m_banner;
}
And then in the CBannerPropSheet::OnInitDialog() function add the line:
m_banner.Attach(this);
et voila Hope that helps...
www.kinkycode.com
[Glossary Manager] [AfterThought Backup Lite]
99 little bugs in the code, 99 little bugs,
Fix 1 bug, recompile....
101 little bugs in the code...
|
|
|
|

|
What about including this banner control in a "CView"?
Andre1234
|
|
|
|

|
It works if you include in a CView... however, your CView will have to have the WS_CLIPCHILDREN style set otherwise you'll see flicker while resizing the view... other than that, it works
www.kinkycode.com
[Glossary Manager] [AfterThought Backup Lite]
99 little bugs in the code, 99 little bugs,
Fix 1 bug, recompile....
101 little bugs in the code...
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.
|
A CWnd-derived control that can attach itself to any window, without the programmer making provisions for it
| Type | Article |
| Licence | CPOL |
| First Posted | 21 Oct 2003 |
| Views | 192,229 |
| Downloads | 1,878 |
| Bookmarked | 130 times |
|
|