ただいま学校の卒業研究でSusieみたいな画像ビューワーを作ろうと思ったんですけど、なにぶんWin32APIは勉強したてなものでよろしくお願いします。
↓にソースを載せます■■■■■■■■■■■■■■■
/********************************************************************************
* ビューワのプロトタイプ? ********************************************************************************/
#define WIN32_LEAN_AND_MEAN
#define STRICT
#include <windows.h>
#define APP_NAME "Viewer"
#define WINDOW_TITLE "Viewerの試作品"
#define WINDOW_X 100
#define WINDOW_Y 100
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
#define ID_hBtn_Exit 1001
/*-------------------------------------------------------------------- 構造体 */
/*-------------------------------------------------------- 関数のプロトタイプ */
LRESULT CALLBACK WndMainProc(HWND, UINT, WPARAM, LPARAM);
ATOM InitApp(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);
/*------------------------------------------------------------ グローバル変数 */
HINSTANCE hInst;
HWND hBtn_Exit = NULL;
HDC hDCBm_Test = NULL;
BITMAP BmInfo;
/********************************************************************************
* メイン関数
********************************************************************************/
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
BOOL bRet;
hInst = hInstance;
if(!InitApp(hInstance)) return FALSE;
if(!InitInstance(hInstance, nCmdShow)) return FALSE;
while((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (bRet == -1)
{
MessageBox(NULL, "GetMessageエラー", "Error", MB_OK);
break;
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int)msg.wParam;
}
/********************************************************************************
* ウィンドウクラスの定義
*
* hInstance : アプリケーションハンドル
* lpszMenuName : メニュー名
*
* 戻り値 : 成功したら固有のアトムを返す; 失敗したら 0
********************************************************************************/
ATOM InitApp(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(wcex);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndMainProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = (LPCSTR)APP_NAME;
wcex.hIconSm = NULL;
return RegisterClassEx(&wcex);
}
/********************************************************************************
* ウィンドウの作成
*
* hInstance : アプリケーションハンドル
* hMenu : メニューハンドル
*
* 戻り値 : 成功したら TRUE; 失敗したら FALSE
********************************************************************************/
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd = NULL;
hWnd = CreateWindowEx(
WS_EX_APPWINDOW,
APP_NAME,
WINDOW_TITLE,
WS_OVERLAPPEDWINDOW,
WINDOW_X,
WINDOW_Y,
WINDOW_WIDTH,
WINDOW_HEIGHT,
NULL,
NULL,
hInstance,
NULL);
if(!hWnd) return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
/********************************************************************************
* メッセージプロシージャの定義(メッセージ処理)
*
* hWnd : ウィンドウハンドル
* Msg : メッセージ
* wParam : ?パラメータ
* lParam : ?パラメータ
*
* 戻り値 : よくわからん
********************************************************************************/
LRESULT CALLBACK WndMainProc(HWND hWnd, UINT Msg,
WPARAM wParam, LPARAM lParam)
{
RECT WindowRect;
PAINTSTRUCT ps;
HDC hDC;
char str[200];
switch(Msg)
{
case WM_CREATE:
HBITMAP hBm_Test;
hDC = GetDC(hWnd);
hDCBm_Test = CreateCompatibleDC(hDC);
// ビットマップの読み込み
hBm_Test = (HBITMAP)LoadImage(NULL, "test.bmp", IMAGE_BITMAP,
0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
GetObject(hBm_Test, (int)sizeof(BITMAP), &BmInfo);
SelectObject(hDCBm_Test, hBm_Test);
DeleteObject(hBm_Test);
ReleaseDC(hWnd, hDC);
// ボタンの作成
hBtn_Exit = CreateWindow("BUTTON",
"exit",
WS_CHILD,
0, 0, 50, 20,
hWnd,
(HMENU)ID_hBtn_Exit,
hInst,
NULL);
// タイトルに幅×高さ×ピクセル単位のビットを表示
wsprintf(str, "%d × %d × %d", BmInfo.bmWidth, BmInfo.bmHeight, BmInfo.bmBitsPixel);
SetWindowText(hWnd, str);
// ウィンドウの更新
ShowWindow(hBtn_Exit,SW_SHOW);
break;
case WM_PAINT:
float floatWidth, floatHeight;
int TargetWidth, TargetHeight;
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &WindowRect);
floatWidth = (float)WindowRect.right / BmInfo.bmWidth;
floatHeight = (float)WindowRect.bottom / BmInfo.bmHeight;
if(floatWidth < floatHeight)
{
TargetWidth = WindowRect.right;
TargetHeight = (int)(BmInfo.bmHeight * floatWidth);
} else {
TargetWidth = (int)(BmInfo.bmWidth * floatHeight);
TargetHeight = WindowRect.bottom;
}
StretchBlt(
hDC, 0, 0, TargetWidth, TargetHeight,
hDCBm_Test, 0, 0, BmInfo.bmWidth, BmInfo.bmHeight,
SRCCOPY);
EndPaint(hWnd, &ps);
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_hBtn_Exit:
SendMessage(hWnd, WM_DESTROY, 0, 0);
break;
}
break;
case WM_DESTROY:
DeleteDC(hDCBm_Test);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
return 0;
}
■■■■■■■■■■■■■■■■■■■■■■■■■
カレントディレクトリにtest.bmpを入れて実験しています
すみません長くて、、、このウィンドウのサイズを変えたときに画面がちらつくんですけど簡単な対処法などありませんか?
どうでもいいんですけど return 0;と return 0L;の違いってあるんですかね・・・
このくらいの処理でちらつくのですか。
floatを使わないで、128倍しといて >> 7 するとか。
HDCをもう一つ用意してそこにStretchBltしてからhDCにBitBltするとか。
WM_ERASEBKGNDでビットマップの領域を塗りつぶさないとか。
あんまり効果ないような気がしますが...
wcex.hbrBackground = (HBRUSH)GetStockObject( NULL_BRUSH );
を使用するようにすればいいのではないでしょうか?
WS_CLIPCHILDREN
もいれておくとよいと思われます。
ツイート | ![]() |