Windows窗口的建立

  • 预备知识

  1. DC

  2. CreateCompatibleDC()   

  3. CreateDIBSection()

  4. SelectObject()

  5. BitBlt()

设备上下文  

  (简称为「DC」)实际上是GDI内部保存的资料结构。设备上下文(与特定的显示设备(如视讯显示器或印表机)相关。对於视讯显示器,设备上下文(总是与显示器上的特定视窗相关。装置内容中的有些值是图形「属性」,这些属性定义了GDI绘图函式工作的细节。

CreateCompatibleDC  

  创建内存DC。假如你要对屏幕进行比较多的GDI(图形设备接口(Graphics Device Interface))函数操作,如果每一步操作 都直接对屏幕DC进行操作,那出现的大多数可能性都是屏幕的闪烁。一个很好的解决方法就是使用内存DC,将这些操作全部先在内存DC上操作,然后依次性在屏幕上进行操作。HDC定义的变量指向一块内存,这块内存用来描述一个设备的相关的内容。

CreateDIBSection 

HBITMAP CreateDIBSection(HDC hdc,CONST BITMAPINFO *pbmi,UINT iUsage,VOID** ppvBits,HANDLE hSection,DWORD dwOffset);

  该函数提供一个指针,该指针指向位图位数据值的地方。可以给文件映射对象提供句柄,函数使用文件映射对象来创建位图,或者让系统为位图分配内存。

  如果函数执行成功,那么返回值是一个指向刚刚创建的与设备无关位图(DIB)的句柄,并且*ppvBits指向该位图的位数据值。

    DIB DDB

  Device-indepentent bitmap  Device-dependent bitmap  

  CreateDIBitmap创建的是设备相关位图句柄 - HBITMAP。

  CreateDIBSection创建的是设备无关位图句柄 - HBITMAP。 

SelectObject 

把一个对象(位图、画笔、画刷等)选入指定的设备描述表。新的对象代替同一类型的老对象。

HGDIOBJ SelectObject(
   HDC hdc,         // handle to DC
   HGDIOBJ hgdiobj  // handle to object
 );

MSDN中的解释:

Selects an object into the device context(选择一个对象到设备上下文中去).

BitBlt

该函数对指定的源设备环境区域中的像素进行位块(bit_block)转换,以传送到目标设备环境。

原型:  

BOOL BitBlt(
  HDC hdcDest, 
  int nXDest, int nYDest, int nWidth, int nHeight, 
  HDC hdcSrc,
  int nXSrc, int nYSrc,
  DWORD dwRop);

参数:   

hdcDest:指向目标设备环境的句柄。

nXDest、nYDest:指定目标矩形区域左上角的X轴和Y轴逻辑坐标

nWidth、nHeight:指定源和目标矩形区域的逻辑宽度和逻辑高度。

hdcSrc:指向源设备环境的句柄。

nXSrc、nYSrc:指定源矩形区域左上角的X轴和Y轴逻辑坐标。

dwRop:指定光栅操作代码。这些代码将定义源矩形区域的颜色数据,如何与目标矩形区域的颜色数据组合以完成最后的颜色。下面列出了一些常见的光栅操作代码:

描述

BLACKNESS

表示使用与物理调色板的索引0相关的色彩来填充目标矩形区域,(对缺省的物理调色板而言,该颜色为黑色)。

DSTINVERT

表示使目标矩形区域颜色取反。

MERGECOPY 

表示使用布尔型AND(与)操作符将源矩形区域的颜色与特定模式组合一起。

MERGEPAINT

通过使用布尔型OR(或)操作符将源矩形区域的颜色取反后与目标矩形区域的颜色合并。

NOTSRCCOPY

将源矩形区域颜色取反,拷贝到目标矩形区域。

NOTSRCERASE

使用布尔类型的OR(或)操作符组合源和目标矩形区域的颜色值,然后将合成的颜色取反。

PATCOPY

将特定的模式拷贝到目标位图上。

PATINVERT

通过使用布尔型XOR(异或)操作符将源和目标矩形区域内的颜色合并。

PATPAINT

通过使用布尔型OR(或)操作符将源矩形区域取反后的颜色值与特定模式的颜色合并。然后使用OR(或)操作符将该操作的结果与目标矩形区域内的颜色合并。

SRCAND

通过使用布尔型AND(与)操作符来将源和目标矩形区域内的颜色合并。

SRCCOPY

将源矩形区域直接拷贝到目标矩形区域。

SRCERASE

通过使用布尔型AND(与)操作符将目标矩形区域颜色取反后与源矩形区域的颜色值合并。

SRCINVERT

通过使用布尔型XOR(异或)操作符将源和目标矩形区域的颜色合并。

SRCPAINT

通过使用布尔型OR(或)操作符将源和目标矩形区域的颜色合并。

WHITENESS

使用与物理调色板中索引1有关的颜色填充目标矩形区域。(对于缺省物理调色板来说,这个颜色就是白色)。

 
 

 Code:

#include <windows.h>
#include <tchar.h>


LRESULT CALLBACK    windowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg)
    {
    case WM_SIZE:
        break;
    case WM_CLOSE:
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        break;
    }

    return  DefWindowProc( hWnd, msg, wParam, lParam );
}

int     WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
    //  1   注册窗口类
    ::WNDCLASSEXA winClass;
    winClass.lpszClassName  =   "Raster";
    winClass.cbSize         =   sizeof(::WNDCLASSEX);
    winClass.style          =   CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
    winClass.lpfnWndProc    =   windowProc;
    winClass.hInstance      =   hInstance;
    winClass.hIcon	        =   0;
    winClass.hIconSm	    =   0;
    winClass.hCursor        =   LoadCursor(NULL, IDC_ARROW);
    winClass.hbrBackground  =   (HBRUSH)(BLACK_BRUSH);
    winClass.lpszMenuName   =   NULL;
    winClass.cbClsExtra     =   0;
    winClass.cbWndExtra     =   0;
    RegisterClassExA(&winClass);

    //  2 创建窗口
    HWND    hWnd   =   CreateWindowExA(
        NULL,
        "Raster",
        "Raster",
        WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
        0,
        0,
        480,
        320, 
        0, 
        0,
        hInstance, 
        0
        );

    UpdateWindow( hWnd );
    ShowWindow(hWnd,SW_SHOW);

    RECT    rt      =   {0};
    GetClientRect(hWnd,&rt);//窗口坐标原点位于窗口左上角。RECT上下左右依然是普遍理解的位置

    int     width   =   rt.right - rt.left;
    int     height  =   rt.bottom - rt.top;
    void*   buffer  =   0;
//得到当前窗口DC
	HDC     hDC     =   GetDC(hWnd);
	HDC     hMem    =   ::CreateCompatibleDC(hDC);



    BITMAPINFO	bmpInfor;
    bmpInfor.bmiHeader.biSize			=	sizeof(BITMAPINFOHEADER);
    bmpInfor.bmiHeader.biWidth			=	width;
    bmpInfor.bmiHeader.biHeight			=	height;
    bmpInfor.bmiHeader.biPlanes			=	1;
    bmpInfor.bmiHeader.biBitCount		=	32;//一个像素占32个bit位4x8
    bmpInfor.bmiHeader.biCompression	=	BI_RGB;
    bmpInfor.bmiHeader.biSizeImage		=	0;
    bmpInfor.bmiHeader.biXPelsPerMeter	=	0;
    bmpInfor.bmiHeader.biYPelsPerMeter	=	0;
    bmpInfor.bmiHeader.biClrUsed		=	0;
    bmpInfor.bmiHeader.biClrImportant	=	0;

    HBITMAP	hBmp    =	CreateDIBSection(hDC,&bmpInfor,DIB_RGB_COLORS,(void**)&buffer,0,0);//buffer是指向图片数组的指针
    SelectObject(hMem,hBmp);//将内存DC和位图关联,DC相当于画板,Bmp相当于纸


    memset(buffer,0,width * height * 4);
    MSG     msg =   {0};
    while(true)//此循环一直在刷新,占用cpu比较高,4核cpu占用率约为25%
    {
        if (msg.message == WM_DESTROY  
            ||msg.message == WM_CLOSE
            ||msg.message == WM_QUIT)
        {
            break;
        }
        if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
        { 
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }

        memset(buffer,0,width * height * 4);
        //! 修改其中一部分
        unsigned char*  rgba    =   (unsigned char*)buffer;
        int             pitch   =   width * 4;//窗口一行像素占的字节数,(一个像素的rgba是4byte)

        memset(rgba + pitch * 10,255, pitch);//将第10行每个像素的rgba都改为255,即为一条白线


        BitBlt(hDC,0,0,width,height,hMem,0,0,SRCCOPY);

    }

    return  0;
}

  

 
 
 
 
 
 
 
 
 
 
 
posted on 2018-11-22 20:47  GavinTin 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/gavintin/p/10003810.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值