15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Window titlebar with gradient colors...

Mercea Mario -- mario@edc.sorostm.ro
Saturday, November 09, 1996

Environment: VC++ 4.1, Win95

  Hi!,

  I want to make the title bar of a window with gradient colors, like
in MS Office 95..., I would be happy if somebody can tell me how can
I do this...

					Thanks...! :)

[Moderator's note: As I recall, the answer is to draw the title bar
in the WM_NCPAINT handler, but if someone out there has some sample
code, I'm sure we'd all appreciate it.]

--

|\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
|    Mario Mercea                        |
| -------------------------------------- |
|    E-Mail: mario@edc.sorostm.ro        |
|   FAX/BBS: +40-(0)56-133423            |
|/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\|




Robert H. Mowery III -- rmowery@csci.csc.com
Tuesday, November 12, 1996

Mercea, 

The moderators note about the WM_NCPAINT handler is correct. There is much
information on this and a good example (although the gradient is not
painted) in Mike Blaszczak's book in the Chapter 7 of the Advanced User
Interface Programming. 
Sorry I do not want to break copyright by pasting the example, but maybe if
Mike is reading this newsgroup he could throw it up here or grab the book
it is worth the money.  While his example does not paint the gradient color
it shows an excellent demonstration of handling the WM_NCPAINT and
customizing the title bar the way you would like it.

Hope this points you in the right direction.

-Robert Mowery


----------
> From: Mercea Mario 
> To: mfc-l@netcom.com
> Subject: Window titlebar with gradient colors...
> Date: Saturday, November 09, 1996 4:41 AM
> 
> Environment: VC++ 4.1, Win95
> 
>   Hi!,
> 
>   I want to make the title bar of a window with gradient colors, like
> in MS Office 95..., I would be happy if somebody can tell me how can
> I do this...
> 
> 					Thanks...! :)
> 
> [Moderator's note: As I recall, the answer is to draw the title bar
> in the WM_NCPAINT handler, but if someone out there has some sample
> code, I'm sure we'd all appreciate it.]
> 
> --
> 
> |\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
> |    Mario Mercea                        |
> | -------------------------------------- |
> |    E-Mail: mario@edc.sorostm.ro        |
> |   FAX/BBS: +40-(0)56-133423            |
> |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\|
> 



rkumar@mail.cswl.com
Wednesday, November 13, 1996

     I call this function from my main frame's WM_NCPAINT handler this 
     paints the title bar from blue to black.
     
     
     void CMainFrame::DrawTitleBar()
     {
        CDC* dc;
        int x,y;
        CRect rc1,rc2;
        dc = GetWindowDC(  );
        GetWindowRect((LPRECT)&rc2 );
     
        // Compute the caption bar's origin. This window has a system box
        // a minimize box, a maximize box, and has a resizeable frame
     
        x = GetSystemMetrics( SM_CXSIZE ) +
                GetSystemMetrics( SM_CXBORDER ) +
                GetSystemMetrics( SM_CXFRAME );
        y = GetSystemMetrics( SM_CYFRAME );
        rc1.left = x;
        rc1.top = y;
     
        // 2*x gives twice the bitmap+border+frame size. Since there are
        // only two bitmaps, two borders, and one frame at the end of the
        // caption bar, subtract a frame to account for this.
     
        rc1.right = rc2.right - rc2.left - 2*x -
                                GetSystemMetrics( SM_CXFRAME );
        rc1.bottom = GetSystemMetrics( SM_CYSIZE );
     
        //draw the caption backgroung
       RECT rectFill;          // Rectangle for filling band
       float fStep;            // How large is each band?
       CBrush Brush;
       int iOnBand;  // Loop index
      
      
       // Determine how large each band should be in order to cover the
       // client with 256 bands (one for every color intensity level)
       fStep = (float)(rc1.right-rc1.left) / 256.0f;
      
       int left;
       // Start filling bands
       for (iOnBand = 0; iOnBand < 256; iOnBand++) 
       {
          left=((rc1.left+((iOnBand+1) * fStep)) > rc1.right)? rc1.right : 
     (rc1.left+((iOnBand+1) * fStep));
                // Set the location of the current band
                SetRect(&rectFill,
                                (int)rc1.left+(iOnBand * fStep),            
        // Upper left X
                                rc1.top,                                    
                                                // Upper left Y
                                (int)left,      // Lower right X
                                rc1.bottom+3);                              
                        // Lower right Y
      
                // Create a brush with the appropriate color for this band
                Brush.CreateSolidBrush(RGB(0, 0, (255 - iOnBand)));
      
                // Fill the rectangle
                dc->FillRect(&rectFill, &Brush);
      
                // Get rid of the brush you created
                Brush.DeleteObject();
        };
     
        // Render the caption. Use the active caption color as the text
        // background.
        CString caption;
                GetWindowText(caption);
        dc->SetBkMode( TRANSPARENT );
        dc->DrawText(caption,(LPRECT)&rc1, DT_LEFT );
        ReleaseDC(dc);
        
     }


Remember that u have to call the base class ncpaint function before calling this
and handel the Wm_Activate and wm_syscommand messages also
as these also affect the title bar
Hope this helps!
                                Ratan
                                rkumar@cswl.com



Frank McGeough -- fm@synchrologic.com
Monday, November 18, 1996

>      I call this function from my main frame's WM_NCPAINT handler this 
>      paints the title bar from blue to black.
>      
>      
>      void CMainFrame::DrawTitleBar()
>      {
>         CDC* dc;
>         int x,y;
>         CRect rc1,rc2;
>         dc = GetWindowDC(  );
>         GetWindowRect((LPRECT)&rc2 );
>      
       lots o' calculations 

       loop doing brush creation and fill rectangles
>

Speaking naively as someone who hasn't done this, I would think
this would cause lots of irritating flashing? Shouldn't these
type of manipulations be done by building the image offscreen
and using some sort of BitBlt operation?




Luiz Carlos C. Marques -- lmarques@cpqd.br
Tuesday, November 19, 1996

[Mini-digest: 3 responses]

Environment: Visual C++ 4.0  Windows 95

	I tried Ratan's code (thanks, Ratan) and it works greatly. But, since I
develop for Windows 95, I had to make minor adjustments. These
adjustments are the following:
- number of bitmaps (syscommands buttons)for frames (WS_OVERLAPPED)
in    win95 is 3: MINIMIZE, RESTORE and CLOSE
- for a resolution of 1024x768 (256 colors) and the default
installation   of Windows 95, the function DrawText draws text beyond
rectangle     bottom limits, so one might wish to provide his own font
type (code     provided below)
- text color was black, so I included a change to white
- I did not provide an override of OnActivate; instead, I deal with
the   activation status of main frame in OnNcPaint, calling DrawTitleBar
or   not, according to such status

	This code worked for any resolution, and the only drawback is that I
did not have the time to implement the font change when main frame is
not active. So, depending on the font one chooses, there might be visual
differences, acceptable or not. The font I choose is standard in Windows
95 installation, so differences are minimized.

(Ratan's code):
  .
  .
  .
>   CString caption;
>            GetWindowText(caption);
>    dc->SetBkMode( TRANSPARENT );

(my additional code):		

		dc->SetTextColor( RGB(255,255,255) );

		CFont fontAux;		   
		LOGFONT	lfFont;
		lfFont.lfHeight =        14;
		lfFont.lfWidth =          0 ;
		lfFont.lfEscapement =     0 ;
		lfFont.lfOrientation =    0 ;
		lfFont.lfWeight =         600 ;
		lfFont.lfItalic =         0 ;
		lfFont.lfUnderline =      0 ;
		lfFont.lfStrikeOut =      0 ;
		lfFont.lfCharSet =        0; 
		lfFont.lfOutPrecision =   1; 
		lfFont.lfClipPrecision =  2 ;
		lfFont.lfQuality =        1 ;
		lfFont.lfPitchAndFamily = VARIABLE_PITCH | FF_MODERN ;
		lstrcpy( lfFont.lfFaceName, "MS SANS SERIF" ) ;

		fontAux.CreateFontIndirect( &lfFont );
		dc->SelectObject( (CFont*) &fontAux );	

		dc->DrawText(caption,(LPRECT)&rc1, DT_LEFT  );
>    ReleaseDC(dc);
    
 }

void CMainFrame::OnNcPaint() 
{
	// TODO: Add your message handler code here
	CMDIFrameWnd::OnNcPaint();
	if ( GetActiveWindow() == (CWnd*) this)
		DrawTitleBar();
}

void CMainFrame::OnSize(UINT nType, int cx, int cy) 
{
	CMDIFrameWnd::OnSize(nType, cx, cy);
	// TODO: Add your message handler code here
	DrawTitleBar();

	
}
-----From: Dong Chen 

But that is exactly what MFC did for the CMiniFrameWnd class. If you take a
look at the CMiniFrameWnd::OnNcPaint() source code (winmini.cpp), you will
find out how the non client area and frame borders are painted.
I don't think it matters since the WM_NCPAINT message is not sent that ofen.
--
Dong
d_chen@ix.netcom.com

-----From: mario@edc.sorostm.ro (Mercea Mario)

>Speaking naively as someone who hasn't done this, I would think
>this would cause lots of irritating flashing? Shouldn't these
>type of manipulations be done by building the image offscreen
>and using some sort of BitBlt operation?

Why don't you post an alternative...? :), commenting it's easy...:)

--

|\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
|    Mercea Mario                        |
|----------------------------------------|
|    BBS/FAX: +40-(0)56-133423           |
|    E-Mail: mario@edc.sorostm.ro        |
|/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\|





| Вернуться в корень Архива |