Last active
January 22, 2019 16:32
-
-
Save beru/b8e585d92d91f73dc64f74584116ffeb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Windows.h> | |
#include <stdio.h> | |
#include <algorithm> | |
struct CStopWatch final | |
{ | |
const char* title; | |
const char* type; | |
LARGE_INTEGER frequency; | |
LARGE_INTEGER startTime; | |
CStopWatch( const char* pszTitle, const char* pszType ) | |
: title( pszTitle ), type( pszType ) | |
{ | |
::QueryPerformanceFrequency( &frequency ); | |
::QueryPerformanceCounter( &startTime ); | |
} | |
~CStopWatch( void ) | |
{ | |
LARGE_INTEGER endTime; | |
::QueryPerformanceCounter( &endTime ); | |
double elapsedSec = 1000 * (endTime.QuadPart - startTime.QuadPart) / (double)frequency.QuadPart; | |
char buf[128]; | |
::sprintf_s( buf, "%.3f msec, %s, %s\n", elapsedSec, title, type ); | |
::OutputDebugStringA( buf ); | |
} | |
}; | |
constexpr size_t MAX_COUNT = 60; | |
void case_FillRect(HDC hDC, const RECT& rc, const char* pszType) | |
{ | |
CStopWatch sw( __FUNCTION__, pszType ); | |
for ( size_t n = 0; n < MAX_COUNT; n++ ) { | |
COLORREF color = RGB(n, n, n); | |
HBRUSH brush = ::CreateSolidBrush( color ); | |
::FillRect( hDC, &rc, brush ); | |
::DeleteObject( brush ); | |
} | |
} | |
void case_ExtTextOut(HDC hDC, const RECT& rc, const char* pszType) | |
{ | |
CStopWatch sw( __FUNCTION__, pszType ); | |
for ( size_t n = 0; n < MAX_COUNT; n++ ) { | |
COLORREF color = RGB(n, n, n); | |
COLORREF bkColorOld = ::SetBkColor( hDC, color ); | |
::ExtTextOutW( hDC, rc.left, rc.top, ETO_OPAQUE, &rc, L"", 0, NULL ); | |
::SetBkColor( hDC, bkColorOld ); | |
} | |
} | |
void case_PatBlt(HDC hDC, const RECT& rc, const char* pszType) | |
{ | |
CStopWatch sw( __FUNCTION__, pszType ); | |
for ( size_t n = 0; n < MAX_COUNT; n++ ) { | |
COLORREF color = RGB(n, n, n); | |
HBRUSH brush = ::CreateSolidBrush( color ); | |
HGDIOBJ brushOld = ::SelectObject( hDC, brush ); | |
::PatBlt( hDC, rc.left, rc.top, rc.right, rc.bottom, PATCOPY ); | |
::SelectObject( hDC, brushOld ); | |
::DeleteObject( brush ); | |
} | |
} | |
static void FillRect_DIB(DWORD* pDIBPixels, RECT rc, int cx, int cy, COLORREF color) | |
{ | |
LONG width = rc.right - rc.left; | |
LONG height = rc.bottom - rc.top; | |
if (rc.top < 0) | |
{ | |
height += rc.top; | |
rc.top = 0; | |
} | |
if (rc.left < 0) | |
{ | |
width += rc.left; | |
rc.left = 0; | |
} | |
if (rc.top >= cy || rc.left >= cx || height < 1 || width < 1) | |
{ | |
return; | |
} | |
if (rc.left + width > cx) | |
{ | |
width = cx - rc.left; | |
} | |
if (rc.top + height > cy) | |
{ | |
height = cy - rc.top; | |
} | |
BYTE r = GetRValue(color); | |
BYTE g = GetGValue(color); | |
BYTE b = GetBValue(color); | |
DWORD dwColor = (r << 16) | (g << 8) | b; | |
pDIBPixels += cx * rc.top + rc.left; | |
if (width == cx) | |
{ | |
std::fill_n(pDIBPixels, cx * height, dwColor); | |
} | |
else | |
{ | |
for (LONG i = 0; i < height; ++i) | |
{ | |
std::fill_n(pDIBPixels, width, dwColor); | |
pDIBPixels += cx; | |
} | |
} | |
} | |
void case_std_fill(DWORD* pDIBPixels, const RECT& rc, int cx, int cy) | |
{ | |
CStopWatch sw( __FUNCTION__, "DIB" ); | |
for ( size_t n = 0; n < MAX_COUNT; n++ ) { | |
COLORREF color = RGB(n, n, n); | |
::FillRect_DIB( pDIBPixels, rc, cx, cy, color ); | |
} | |
} | |
//! Main関数 | |
int WINAPI wWinMain( | |
HINSTANCE hInstance, //!< handle to current instance | |
HINSTANCE hPrevInstance, //!< handle to previous instance | |
LPWSTR lpCmdLine, //!< pointer to command line | |
int nCmdShow //!< show state of window | |
) | |
{ | |
::SetProcessDPIAware(); | |
HWND hDesktopWnd = ::GetDesktopWindow(); | |
RECT rc; | |
::GetWindowRect( hDesktopWnd, &rc ); | |
int cx = rc.right - rc.left; | |
int cy = rc.bottom - rc.top; | |
HDC hDesktopDC = ::GetDC( hDesktopWnd ); | |
HDC hCompatibleDC_DDB = ::CreateCompatibleDC( NULL ); | |
HDC hCompatibleDC_DIB = ::CreateCompatibleDC( NULL ); | |
HBITMAP hDDB = ::CreateBitmap( cx, cy, 3, 32, NULL ); | |
::SelectObject( hCompatibleDC_DDB, hDDB ); | |
BITMAPINFO bmi = {0}; | |
BITMAPINFOHEADER& bmih = bmi.bmiHeader; | |
bmih.biSize = sizeof(bmih); | |
bmih.biBitCount = 32; | |
bmih.biWidth = cx; | |
bmih.biHeight = -cy; | |
bmih.biPlanes = 1; | |
bmih.biCompression = BI_RGB; | |
bmih.biSizeImage = 0; | |
bmih.biXPelsPerMeter = 0; | |
bmih.biYPelsPerMeter = 0; | |
bmih.biClrUsed = 0; | |
bmih.biClrImportant = 0; | |
void* pvBits = nullptr; | |
HBITMAP hDIB = CreateDIBSection( | |
NULL, | |
&bmi, | |
DIB_RGB_COLORS, | |
&pvBits, | |
NULL, | |
0 | |
); | |
::SelectObject( hCompatibleDC_DIB, hDIB ); | |
for (int i = 0; i < 8; ++i) | |
{ | |
char buff[64]; | |
sprintf_s(buff, "x, y, w, h : %d, %d, %d, %d\n", rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top); | |
::OutputDebugStringA(buff); | |
case_FillRect( hCompatibleDC_DDB, rc, "DDB" ); | |
case_ExtTextOut( hCompatibleDC_DDB, rc, "DDB" ); | |
case_PatBlt( hCompatibleDC_DDB, rc, "DDB" ); | |
case_FillRect( hCompatibleDC_DIB, rc, "DIB" ); | |
case_ExtTextOut( hCompatibleDC_DIB, rc, "DIB" ); | |
case_PatBlt( hCompatibleDC_DIB, rc, "DIB" ); | |
case_std_fill( (DWORD*)pvBits, rc, cx, cy ); | |
rc.right >>= 1; | |
rc.bottom >>= 1; | |
} | |
::DeleteObject( hDDB ); | |
::DeleteObject( hDIB ); | |
::DeleteDC( hCompatibleDC_DDB ); | |
::DeleteDC( hCompatibleDC_DIB ); | |
::ReleaseDC( hDesktopWnd, hDesktopDC ); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
実行環境
OS : Windows 10 バージョン 1803
CPU : Core i5-4670
GPU : NVIDIA GeForce GTX 1070
実行結果