当需要设置位图的混合模式时,应该使用ID2D1DeviceContext而不是ID2D1RenderTarget。
代码如下:
#define WIN32_LEAN_AND_MEAN #include <windows.h> #include <comdef.h> #include <d2d1.h> #include <d2d1_1.h> #include <d3d11.h> #pragma comment(lib,"D2d1.lib") #pragma comment(lib,"D3D11.lib") #include <iostream> #include <string> void printError(const std::string& msg, HRESULT err) { std::cerr << "[ERROR] " << msg << ": " << _com_error(err).ErrorMessage() << std::endl; assert(false); } int main(int argc, char* argv[]) { ID2D1Factory1* mD2DFactory = nullptr; ID3D11Device* mD3DDevice = nullptr; ID3D11DeviceContext* mD3DDeviceContext = nullptr; IDXGIDevice* mDXGIDevice = nullptr; ID2D1Device* mD2DDevice = nullptr; HRESULT err; // Create factories first; they don't depend on anything. err = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory1), // get a Direct2D 1.1 factory, (void**)&mD2DFactory); if (err != S_OK) { printError("fatal: Could not create Direct2D factory!", err); return 1; } // Initialize DirectX 11.1 D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1 }; err = D3D11CreateDevice(NULL, // first adapter D3D_DRIVER_TYPE_HARDWARE, NULL, // software rasterizer DLL handle D3D11_CREATE_DEVICE_SINGLETHREADED // better performance | D3D11_CREATE_DEVICE_BGRA_SUPPORT, // required for Direct2D featureLevels, sizeof(featureLevels) / sizeof(D3D_FEATURE_LEVEL), D3D11_SDK_VERSION, // docs say use this &mD3DDevice, NULL, // don't care what feature level we got &mD3DDeviceContext); if (err != S_OK) { printError("fatal: could not create a Direct3D 11.1 device", err); return 1; } err = mD3DDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)&mDXGIDevice); if (err != S_OK) { printError("fatal: Direct3D device is not IDXGIDevice", err); return 1; } // Initialize Direct2D err = mD2DFactory->CreateDevice(mDXGIDevice, &mD2DDevice); if (err != S_OK) { printError("fatal: could not create Direct2D device", err); return 1; } //---------------- Create the bitmap -------------------- ID2D1DeviceContext* mDC = nullptr; ID2D1Bitmap1* mBitmap = nullptr; int width = 13, height = 13; float dpi = 76.0f; err = mD2DDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &mDC); if (err) { printError("Could not create device context", err); return 1; } D2D1_BITMAP_PROPERTIES1 bitmapProps; bitmapProps.pixelFormat.format = DXGI_FORMAT_B8G8R8A8_UNORM; bitmapProps.pixelFormat.alphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED; bitmapProps.dpiX = dpi; bitmapProps.dpiY = dpi; bitmapProps.bitmapOptions = D2D1_BITMAP_OPTIONS_CANNOT_DRAW | // can use for SetTarget() D2D1_BITMAP_OPTIONS_CPU_READ; bitmapProps.colorContext = nullptr; err = mDC->CreateBitmap({ UINT32(width), UINT32(height) }, nullptr, 0, bitmapProps, &mBitmap); if (err == S_OK) { mDC->SetTarget(mBitmap); } else { printError("Could not create bitmap (" + std::to_string(width) + "x" + std::to_string(height) + ")", err); return 1; } std::cout << "Success!" << std::endl; return 0; }
类似的例子:per-pixel transparent window using Windows Composition engine in C++