• 【转载】FAQ: Window Regions


    链接地址:

    http://comrade.ownz.com/docs/regions.html

    FAQ: Window Regions

    I have tried to collect a lot of information on window regions and resources on them. If you think I should add something more, e-mail me.

    What are window regions?

    Window regions allow you to create non-square Windows. The "regions" themselves are represented as objects (HRGN), and can be assigned to a particular window (HWND) using the SetWindowRgn API.
    The official documentation for regions can be found on MSDN site here: http://msdn.microsoft.com/library/en-us/gdi/regions_7ab7.asp.

    How do I create a region?

    You can use the following API to create a window region:

    • CreateEllipticRgn
    • CreateEllipticRgnIndirect
    • CreatePolygonRgn
    • CreatePolyPolgyonRgn
    • CreateRectRgn
    • CreateRectRgnIndirect
    • CreateRoundRectRgn
    • ExtCreateRegion

    For exact information on the functions, see the official documentation.

    How do I create more complex regions?

    To create complex regions, you can combine two regions using the CombineRgn function. The function allows you to take 2 regions, and combine them in various ways to produce a 3rd region (the destination region). For the list of possible combinations, see the official documentation.

    How do I create regions out of images?

    Creating a region out of an image means to create a window whose shape exactly matches the outline of a particular image. The image contains a region that is defined as transparency - meaning the window that shows that image should be transparent in those parts. To create such region manually, you can program a simple loop to subtract the transparent pixels from an initially rectangular region:

    HRGN hRegion = CreateRectRgn(0, 0, width_of_image, height_of_image);
    
    for (int y = 0; y < height_of_image; y++) {
        for (int x = 0; x < width_of_image; x++) {
           if (image is transparent at (x, y)) {
             // create a dummy region for destination (it will be overwritten later anyway)
             HRGN hRegionDest = CreateRectRgn(0, 0, 1, 1);
             // create the region that represents the transparent pixel we want to subtract
             HRGN hRegionPixel = CreateRectRgn(x, y, x+1, y+1);
             // subtract the pixel from our current region, and save the new region into hRegionDest
             // essentially: hRegionDest = hRegion - hRegionPixel
             CombineRgn(hRegionDest, hRegion, hRegionPixel, RGN_XOR);
             // delete the old region, and substitute with the new destination region
             DeleteObject(hRegion);
             hRegion = hRegionDest;
           }
        }
    }
    
    // at this point, we have the region in hRegion, and we can assign it to a window using SetWindowRgn
    
    

    The above algorithm is very slow, particularly for very large images. However, you can run it once, save the region data, and then restore it later. Check the Anything extra? category for optimizations to the algorithm.

    How do I save/restore regions?

    To save a region, retrieve its internal composition using the GetRegionData API. Save the binary data into a file, or some other location you like:

    // we are given a region hRegion to save
    DWORD dwRegionSize = GetRegionData(hRegion, 0, NULL);
    LPRGNDATA lpRgnData = (LPRGNDATA) malloc(dwRegionSize);
    GetRegionData(hRegion, dwRegionSize, lpRgnData);
    // save lpRgnData into a file or somewhere else
    

    To restore a region from a saved location, use the ExtCreateRegion API (set lpXform to NULL, nCount to the size of the saved buffer in bytes, and lpRgnData to the pointer to the saved buffer):

    // we are given a pointer to the region buffer lpRgnData, and its size in dwRegionSize
    HRGN hRegion = ExtCreateRegion(NULL, dwRegionSize, lpRgnData);
    

    So as you can see, GetRegionData and ExtCreateRegion are complements of each other - the former is used to convert a region into a binary data, and the latter to do the reverse.

    How do I create transparent/translucent windows?

    You want the SetLayeredWindowAttributes API.

    In-depth tutorials?

    Yes, there is plenty of stuff online. I noted some interesting ones, and here they are in no particular order:

    Are there any tools/libraries to pre-create regions from images?

    Yes, there are plenty. I have collected some links from the web over the years:

    QvasiModo's MakeRegion

    This is an excellent tool which I only find out about recently. The operation is pretty much self-explanatory: start MakeRegion.exe, go to Image -> Load, and pick an image. After that, choose what colour will be defined as the transparent colour. You can do so either by pointing to it in an image using the Image -> Pick transparent color tool, or by entering its explicit RGB value by going to Image -> Enter trans. color RGB. The program will then build the region data. You can save it by going to File -> Save As. It will offer you to save it as a .rgn file. In your own program, you can load this .rgn file straight in as binary data, and pass it through ExtCreateRegion API to get an hRegion out of it.
    The tool even allows you to set tolerance levels, meaning it will except transparency colours that are not exactly what you picked, but are within a certain range. As well, the tool allows you to check the actual region composition as an array of rectangles.
    It was first mentioned on the asmcommunity forums here. The attachment is mirrored here. The author is QvasiModo.

    OnlyTools EdgeTracer

    This is a commercial tool I found on Google. You can read more about it here. The screenshot looks nice - but the program costs $29.

    The RGN Generator

    A simple tool that lets you pick an image, enter the transparency colour and generate region data out of it. You can read it about it here, or download the mirrored version here.

    comrade's Region Cutter

    This is a small tool which I wrote many years ago to complement my tutorial on window regions. It is very simply: you pick a bitmap file, the destination region file, the transparency colour, and hit the Generate button.
    You can download it here.

    CContourBitmap Class

    This is a C++ class for creating regions from bitmaps. It works by subtracting transparent pixels from a rectangular region. I have never tried it, but the author's name is Wolfgang, and you know that Mozart was one smart bloke.

    CRegionCreater

    This is a simple C++ class that implements a single function from converting a bitmap handle to a region.

    CreateRegionFromFile

    This is a function for converting a bitmap handle to a region, given some transparency colour.

    Anything extra?

    • f0dder's customshape sources - a hacker named f0dder took the time to optimize the region creation routine. The results are impressive: 20ms versus 871ms for the old algorithm (as described above).
    • Useful functions for Regions - the dude made a CreateTileRegion and CreateStretchRegions functions, for tiling and stretching regions, respectively.
    • Custom light-weight Regions - the guy didn't like the regular window region API, so he made C++ wrappers around it.
    • Shapes and Regions (.NET) - some example for creating and testing regions in C# (.NET).
    • Irregular shaped buttons - an example on how to combine regions and owner-drawning of buttons to create some crazy buttons. Pretty cool.
  • 相关阅读:
    项目--Asp.net全局变量的设置和读(web.config 和 Gloab)
    项目--后台代码提示
    项目--给项目添加提示声音
    项目--正则表达式
    项目--HTML Canvas 和 jQuery遍历
    项目--用户自定义控件
    Bzoj2120/洛谷P1903 数颜色(莫队)
    Poj2482 Stars in Your Window(扫描线)
    Poj2182 Lost Cows(玄学算法)
    Poj3468 A Simple Problem with Integers (分块)
  • 原文地址:https://www.cnblogs.com/eaglexmw/p/15293122.html
Copyright © 2020-2023  润新知