程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> win32自繪按鈕,使用GDI+(一),win32gdi

win32自繪按鈕,使用GDI+(一),win32gdi

編輯:關於C語言

win32自繪按鈕,使用GDI+(一),win32gdi


第一次寫隨筆,我本來想將win32窗口的標題欄設置成漸變色,像這樣的效果

但發現找不到設置標題欄屬性的api,SetWindowLong也只是增減窗口的固定的樣式而已。所以想到一個思路,把標題欄去掉,自己繪制一個標題欄,包括標題欄上的按鈕都自己來繪制創建。這裡用到了gdi+,對於這個庫也是剛接觸到的。

最後程序實現的效果如下。

對顏色值對應的顏色還不太了解,所以看起來有點丑。

代碼:

#ifndef ULONG_PTR
#define ULONG_PTR unsigned long*
#endif
#include <windows.h>  
//#include <objidl.h>  
#include <gdiplus.h>  
using namespace Gdiplus; 
#pragma comment (lib,"Gdiplus.lib") 
#define ID_BUTTON1 1 
#define ID_BUTTON2 2
HINSTANCE hInst;

void LoadBkImge(HDC hdc)
{
    Graphics graphics(hdc); 
   Image image(L"pic1.png");
   graphics.DrawImage(&image,0,0);
}
 

void FillRec(HDC hdc,Rect myRect,Color* colors,float *positions,int i) 
{ 
    Graphics graphics(hdc); 
   //多彩漸變色
    LinearGradientBrush myLinearGradientBrush(
       myRect,
       Color(255,255,255,0),
       Color(255,255,0,0),
       LinearGradientModeVertical
       );//LinearGradientModeHorizontal*/
  
      myLinearGradientBrush.SetInterpolationColors(colors, positions, i);
      graphics.FillRectangle(&myLinearGradientBrush,myRect);
} 

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow) 
{ 
   HWND                hWnd; 
   MSG                 msg; 
   WNDCLASS            wndClass; 
   GdiplusStartupInput gdiplusStartupInput; 
   ULONG_PTR           gdiplusToken; 
   hInst=hInstance;
    
   // Initialize GDI+.  
   GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); 
    
   wndClass.style          = CS_HREDRAW | CS_VREDRAW|DS_CENTER; 
   wndClass.lpfnWndProc    = WndProc; 
   wndClass.cbClsExtra     = 0; 
   wndClass.cbWndExtra     = 0; 
   wndClass.hInstance      = hInstance; 
   wndClass.hIcon          = LoadIcon(NULL, IDI_APPLICATION); 
   wndClass.hCursor        = LoadCursor(NULL, IDC_ARROW); 
   wndClass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH); 
   wndClass.lpszMenuName   = NULL; 
   wndClass.lpszClassName  = TEXT("Gdiplustest"); 
    
   RegisterClass(&wndClass); 
    
   hWnd = CreateWindow( 
      TEXT("Gdiplustest"), 
      TEXT("Gdiplustest"),
      WS_OVERLAPPED|WS_POPUP,   
      CW_USEDEFAULT,          
      CW_USEDEFAULT,        
      400,           
      250,         
      NULL,                  
      NULL,                   
      hInstance,             
      NULL);                 
    
   ShowWindow(hWnd, iCmdShow); 
   UpdateWindow(hWnd); 
    
   while(GetMessage(&msg, NULL, 0, 0)) 
   { 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
   } 
    
   GdiplusShutdown(gdiplusToken); 
   return msg.wParam; 
}  
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,  
   WPARAM wParam, LPARAM lParam) 
{ 
   static HDC   hdc; 
   static HWND hButton1,hButton2;
   PAINTSTRUCT  ps; 
   LPDRAWITEMSTRUCT pdis;
    
   switch(message) 
   { 
   case WM_CREATE:
       {
           //窗口居中顯示
           int scrWidth,scrHeight;
           RECT rect;
           scrWidth=GetSystemMetrics(SM_CXSCREEN);
           scrHeight=GetSystemMetrics(SM_CYSCREEN);
           GetWindowRect(hWnd,&rect);
           rect.left=(scrWidth-rect.right)/2;
           rect.top=(scrHeight-rect.bottom)/2;
           SetWindowPos(hWnd,HWND_TOP,rect.left,rect.top,rect.right,rect.bottom,SWP_SHOWWINDOW);
           hButton1=CreateWindow("button","",WS_CHILD|WS_VISIBLE|BS_OWNERDRAW,310,5,40,30,hWnd,(HMENU)ID_BUTTON1,hInst,NULL);
           hButton2=CreateWindow("button","",WS_CHILD|WS_VISIBLE|BS_OWNERDRAW,355,5,40,30,hWnd,(HMENU)ID_BUTTON2,hInst,NULL);

           //
           hdc=GetDC(hWnd);
           LoadBkImge(hdc);
           return 0;
       }
   case WM_SIZE:
       return 0;
   case WM_PAINT:
       {
        hdc = BeginPaint(hWnd, &ps); 
        //Draw1(hdc); 
        Rect myRect(0,0,400,40);

        //
       Color colors[]={
       Color(255,255,255),
       Color(247,247,247),
       Color(231,235,139),
       Color(214,223,231),
       Color(181,178,181)
       };
      float positions[]={
       0.0f,
       0.125f,
       0.5f,
       0.875f,
       1.0f
      };
        FillRec(hdc,myRect,colors,positions,5);

      EndPaint(hWnd, &ps); 
      return 0; 
       }
   case WM_COMMAND:
       {
           switch(wParam)
            {
           case ID_BUTTON1:
               {
                   MessageBox(NULL," Undefined","",MB_OK);
                   break;
               }
           case ID_BUTTON2:
                {
                    PostQuitMessage(0); 
                    break;
                }
                //
           }

       return 0;

       }

   case WM_DRAWITEM:
       {

            pdis=(LPDRAWITEMSTRUCT)lParam;
            //SetBkMode(pdis->hDC, TRANSPARENT );
            FillRect(pdis->hDC,&pdis->rcItem,NULL);
            FrameRect(pdis->hDC,&pdis->rcItem,(HBRUSH)GetStockObject(BLACK_BRUSH));

            int cx=pdis->rcItem.right-pdis->rcItem.bottom;
            int cy=pdis->rcItem.bottom-pdis->rcItem.top;

            switch(pdis->CtlID)
            {

                case ID_BUTTON1:
                {
                        Graphics graphics(pdis->hDC); 
                        Rect rectt(0,0,40,30);
                        Color colors[]={
                        Color(247,247,247),
                        Color(231,235,139),
                        Color(214,223,231),
                        };
                        float positions[]={
                        0.0f,
                        0.5f,
                        1.0f
                        };
                        FillRec(pdis->hDC,rectt,colors,positions,3);
                        {
                        SolidBrush  m_pBrush(Color(255,130,130,130));
                        PointF point1(0.0f, 00.0f);
                        PointF point2(30.0f, 20.0f);
                        PointF point3(10.0f, 30.0f);
                        PointF points[3] = {point1, point2, point3};
                        graphics.FillPolygon(&m_pBrush, points, 3, FillModeAlternate); 
                        }
                        
                        break;
                }

                case ID_BUTTON2:
                {
                    Graphics graphics(pdis->hDC); 
                    Rect rectt(0,0,40,30);
                    Color colors[]={
                    Color(247,247,247),
                    Color(231,235,139),
                    Color(214,223,231),
                    };
                    float positions[]={
                    0.0f,
                    0.5f,
                    1.0f
                    };
                    FillRec(pdis->hDC,rectt,colors,positions,3);
        
                    SolidBrush  m_pBrush(Color(255,130,130,130));
                    PointF point1(0.0f, 7.0);
                    PointF point2(6.0f, 0.0f);
                    PointF point3(40.0f, 23.0f);
                    PointF point4(34.0f, 30.0f);
                    PointF points[4] = {point1, point2, point3,point4};
                    graphics.FillPolygon(&m_pBrush, points, 4, FillModeAlternate);
                    //
                    PointF point5(0.0f, 23.0f);
                    PointF point6(34.0f, 0.0f);
                    PointF point7(40.0f, 7.0f);
                    PointF point8(6.0f, 30.0f);

                    PointF points2[4] = {point5, point6, point7,point8    };
                    graphics.FillPolygon(&m_pBrush, points2, 4, FillModeAlternate); 
                    }
                break;
            }
          //if (pdis->itemState & ODS_SELECTED)
              // InvertRect (pdis->hDC, &pdis->rcItem) ;
          
              //  Draw a focus rectangle if the button has the focus
          
          if (pdis->itemState & ODS_FOCUS)
          {
               pdis->rcItem.left   += cx / 16 ;
               pdis->rcItem.top    += cy / 16 ;
               pdis->rcItem.right  -= cx / 16 ;
               pdis->rcItem.bottom -= cy / 16 ;
               
               DrawFocusRect (pdis->hDC, &pdis->rcItem) ;
          }
          return 0 ;
       }

   case WM_DESTROY: 
      PostQuitMessage(0); 
      return 0; 
   case WM_LBUTTONDOWN:
      SendMessage(hWnd,WM_NCLBUTTONDOWN,HTCAPTION,0);
      return 0;
   default: 
      return DefWindowProc(hWnd, message, wParam, lParam); 
   } 
}

說明:

這裡有一個嚴重的問題,如何設置按鈕的背景透明?臨時的解決辦法是將按鈕填充相同的漸變色。如畫的標題欄的五種漸變色的position數組值為

      float positions[]={
       0.0f,
       0.125f,
       0.5f,
       0.875f,
       1.0f
      };

顏色為

       Color colors[]={
       Color(255,255,255),
       Color(247,247,247),
       Color(231,235,139),
       Color(214,223,231),
       Color(181,178,181)
       };

根據坐標計算出按鈕的漸變色顏色和位置分別為

       Color colors[]={
       Color(247,247,247),
       Color(231,235,139),
       Color(214,223,231),
       };
      float positions[]={
       0.0f,0.5f,1.0f
      };

這種方法看起來挺笨的,所以最後留兩個問題。

問題一:如何設置系統菜單欄為漸變色?

問題二:按鈕背景如何透明?

參考:雜七雜八找了很多資料

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved