挖位图,做窗口.

//CRgnBitmap.h



#ifndef RGN_BITMAP_H

#define RGN_BITMAP_H



#include <windows.h>





class CRgnBitmap

{

public:

    CRgnBitmap();

    ~CRgnBitmap();



    bool LoadBmp(HINSTANCE hInstance, LPCSTR lp);



    HRGN GetRgn(HWND hwnd);



    HBITMAP GetHBitmap();



    int GetWidth();

    int GetHeight();



private:

    HBITMAP m_hBitmap;



    int m_width;

    int m_height;



};



inline HBITMAP CRgnBitmap::GetHBitmap()

{

    return m_hBitmap;

}



inline int CRgnBitmap::GetWidth()

{

    return m_width;

}



inline int CRgnBitmap::GetHeight()

{

    return m_height;

}



#endif



//================================

//CRgnBitmap.cpp



#include "CRgnBitmap.h"





/**

 * 构造函数.

 */

CRgnBitmap::CRgnBitmap()

    : m_hBitmap(NULL),

      m_width(0),

      m_height(0)

{

}



/**

 * 析构函数.

 */

CRgnBitmap::~CRgnBitmap()

{

    if (m_hBitmap != NULL)

    {

        DeleteObject(m_hBitmap);

        m_hBitmap = NULL;

    }

}



bool CRgnBitmap::LoadBmp(HINSTANCE hInstance, LPCSTR lp)

{

    m_hBitmap = LoadBitmap(hInstance, lp);



    if (m_hBitmap == NULL)

    {

        return false;

    }



    BITMAP bitmap;

    GetObject(m_hBitmap, sizeof(BITMAP),   &bitmap);   //得到位图数据  



    m_width  = bitmap.bmWidth;

    m_height = bitmap.bmHeight;



    return true;

}



/**

 *   获得一个由位图创建的区域  

 */ 

HRGN CRgnBitmap::GetRgn(HWND hwnd)

{

    HDC hdc = GetDC(hwnd);  

    HDC ExterDC = CreateCompatibleDC(hdc);  



    BITMAP backBitmap;

    GetObject(m_hBitmap, sizeof(BITMAP),   &backBitmap);   //得到位图数据  

    SelectObject(ExterDC, m_hBitmap);   //把位图选进   ExterDC  



    RECT rect;

    GetClientRect(hwnd, &rect);   //得到窗口原点坐标  



    //计算区域的原点  

    int rgn_x0   =   rect.left   +   GetSystemMetrics(SM_CYFIXEDFRAME);   //加上左边框  

    int rgn_y0   =   rect.top   +   GetSystemMetrics(SM_CYCAPTION)   +   GetSystemMetrics(SM_CYFIXEDFRAME);   //加上上边框和标题栏  



    //创建一个容纳位图的区域.Region的坐标是在窗口范围内的坐标。  

    HRGN bitmapRgn = CreateRectRgn(rgn_x0, rgn_y0, rgn_x0+m_width, rgn_y0+m_height);  



    COLORREF   diffColor   =   0x00a63000;   //透明色   0x00bbggrr    

    COLORREF   colorRef;   //颜色值  



    int   width   =   0;  

    //扫描所有像素,去除图像内部的空白  

    for(int j = 0; j < m_height; j++)   //从上到下  

    {

        width = 0;  

        for(int i = 0; i <= m_width; i++)   //从左到右  

        {  

            colorRef = GetPixel(ExterDC, i, j);  



            if((i > backBitmap.bmWidth-1 || colorRef != diffColor) && width != 0)  

            {

                HRGN tmpRgn = CreateRectRgn(rgn_x0+i-width, rgn_y0+j, rgn_x0+i, rgn_y0+j+1);   //rgn不包括底边和右边  

                CombineRgn(bitmapRgn, tmpRgn, bitmapRgn, RGN_XOR);  

                DeleteObject(tmpRgn);



                width   =   0;  

            }



            if(colorRef   ==   diffColor)  

            {  

                width++;   //长度  

            }  

        }  

    }  



    DeleteDC(ExterDC);  

    ReleaseDC(hwnd,   hdc);  



    return   bitmapRgn; 

}





//================

//main.cpp



// BeatufulGUI.cpp : 定义应用程序的入口点。

//



#include "BeatufulGUI.h"



#include "CRgnBitmap.h"







#define MAX_LOADSTRING 100







// 全局变量:

HINSTANCE hInst;	// 当前实例



CRgnBitmap* g_pBgRgnBitmap;







int WINAPI WinMain(HINSTANCE hInstance,

            HINSTANCE hPrevInstance,

            LPSTR    lpCmdLine,

            int       nCmdShow)

{

	WNDCLASSEX wcex;



	wcex.cbSize         = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;

	wcex.lpfnWndProc	= WndProc;

	wcex.cbClsExtra		= 0;

	wcex.cbWndExtra		= 0;

	wcex.hInstance		= hInstance;

	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_BEATUFULGUI));

	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);

	wcex.hbrBackground	= (HBRUSH)(COLOR_BACKGROUND);

	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_BEATUFULGUI);

	wcex.lpszClassName	= "BmpWindow";

	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));



	RegisterClassEx(&wcex);



	// 执行应用程序初始化:

	if (!InitInstance (hInstance, nCmdShow))

	{

		return 0;

	}



	// 主消息循环:

        BOOL bRet;

        MSG msg;

        while ( (bRet = GetMessage(&msg, NULL, 0, 0)) != 0)

        {

                if (bRet == -1)

                {

                    //fatal error

                }

                else

                {

                    TranslateMessage(&msg);

                    DispatchMessage(&msg);

                }

        }



    ///*

    //If the function retrieves a message other than WM_QUIT, the return value is nonzero.



    //If the function retrieves the WM_QUIT message, the return value is zero. 



    //If there is an error, the return value is -1. For example, the function fails if hWnd is an invalid window handle or lpMsg is an invalid pointer.

    //To get extended error information, call GetLastError.



    //Warning  

    //Because the return value can be nonzero, zero, or -1, avoid code like this:



    //while (GetMessage( lpMsg, hWnd, 0, 0)) ...

    //    The possibility of a -1 return value means that such code can lead to fatal application errors.

    //*/



        return (int) msg.wParam;

}





//

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)

{

    hInst = hInstance; // 将实例句柄存储在全局变量中



    //开始用背景图的数据,计算窗口的尺寸和位置

    g_pBgRgnBitmap = new CRgnBitmap();

    

    g_pBgRgnBitmap->LoadBmp(hInst, (LPCSTR)IDB_BITMAP_BACK);



    //获取桌面大小,以便窗口显示在中间

    int DesktopWidth = GetSystemMetrics(SM_CXSCREEN);

    int DesktopHeight = GetSystemMetrics(SM_CYSCREEN);



    //窗口的尺寸

    int WindowWidth = g_pBgRgnBitmap->GetWidth();

    int WindowHeight = g_pBgRgnBitmap->GetHeight();



    //计算窗口起始坐标

    int StartX = (DesktopWidth - WindowWidth)/2;

    int StartY = (DesktopHeight - WindowHeight)/2;



    //创建窗体

    HWND hWnd = CreateWindow("BmpWindow", 

                            "BmpWin", //窗口名字

                            WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU,

                            StartX, StartY, 

                            WindowWidth, WindowHeight, 

                            NULL, NULL, 

                            hInstance, NULL);



       if (hWnd == NULL)

        {

                return FALSE;

        }



       ShowWindow(hWnd, nCmdShow);

       UpdateWindow(hWnd);



       return TRUE;

}



/**

//  目的: 处理主窗口的消息。

//

//  WM_PAINT	- 绘制主窗口

//  WM_DESTROY	- 发送退出消息并返回

*/

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

        PAINTSTRUCT ps;

        HDC hdc;



        switch (message)

        {

        case WM_CREATE:

                {

                    HRGN windowRgn = g_pBgRgnBitmap->GetRgn(hWnd);

                    SetWindowRgn(hWnd, windowRgn, TRUE);

                }

                break;



        case WM_PAINT:

        {

            hdc = BeginPaint(hWnd, &ps);



            HDC ExterDC = CreateCompatibleDC(hdc);  



            HBITMAP hTmpBitmap = g_pBgRgnBitmap->GetHBitmap();



            BITMAP backBitmap;

            GetObject(hTmpBitmap, sizeof(BITMAP), &backBitmap);   //得到位图数据  

            SelectObject(ExterDC, hTmpBitmap);   //把位图选进   ExterDC  



            BitBlt(hdc, 0, 0, backBitmap.bmWidth, backBitmap.bmHeight, ExterDC, 0, 0, SRCCOPY);   //把位图从 ExterDC copy 到 hdc  



            DeleteDC(ExterDC);  

            ReleaseDC(hWnd, hdc);



            EndPaint(hWnd, &ps);

        }

        break;



        case WM_NCHITTEST:

        {

            PostMessage(hWnd, WM_LBUTTONDOWN, wParam, lParam);



            return HTCAPTION;

        }

        break;



        case WM_DESTROY:

                if (g_pBgRgnBitmap != NULL)

                {

                    delete g_pBgRgnBitmap;

                    g_pBgRgnBitmap = NULL;

                }



                PostQuitMessage(0);



                break;



        default:

                return DefWindowProc(hWnd, message, wParam, lParam);

        }

        return 0;

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王旺旺旺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值