プログラムの説明は、IPFundamentals から確認してください。 By Cryst.
/*
Copyright (c) 2011, Cryst.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.
* Neither the name of the Cryst nor the names of its contributors may be used to endorse or
promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
Copyright (c) 2011, Cryst.
All rights reserved.

ソースコード形式かバイナリ形式か、変更するかしないかを問わず、以下の条件を満たす場合に
限り、再頒布および使用を許可します。

* ソースコードを再頒布する場合、上記の著作権表示、本条件一覧、および 下記免責条項を
含めること。
* バイナリ形式で再頒布する場合、頒布物に付属のドキュメント等の資料に、上記の著作権
表示、本条件一覧、および下記免責条項を含めること。
* 書面による特別の許可なしに、本ソフトウェアから派生した製品の宣伝または販売促進に、
Cryst の名前またはコントリビューターの名前を使用してはならない。

本ソフトウェアは、著作権者およびコントリビューターによって「現状のまま」提供されており、
明示黙示を問わず、商業的な使用可能性、および特定の目的に対する適合性に関する暗黙の保証
も含め、またそれに限定されない、いかなる保証もありません。著作権者もコントリビューター
も、事由のいかんを問わず、損害発生の原因いかんを問わず、かつ責任の根拠が契約であるか
厳格責任であるか(過失その他の)不法行為であるかを問わず、仮にそのような損害が発生する
可能性を知らされていたとしても、本ソフトウェアの使用によって発生した(代替品または代用
サービスの調達、使用の喪失、データの喪失、利益の喪失、業務の中断も含め、またそれに限定
されない)直接損害、間接損害、偶発的な損害、特別損害、懲罰的損害、または結果損害につい
て、一切責任を負わないものとします。
*/

/** bmp ファイルを表示するプログラムの雛形
コンパイル方法:
gcc -O3 -Wall -mno-cygwin -mwindows -o bmpLoad bmpLoad.c
使い方:
1、bmpLoad [BMP_file_name]
  コマンドを直接起動するか、コマンドラインにBMPファイル名を指定して起動
  explorer.exe でプログラムのアイコンにBMPファイルをドラッグ&ドロップする
2、プログラムの画像表示画面にBMPファイルをドラッグ&ドロップする
*/

#include <stdio.h>
#include <windows.h>
#include <tchar.h> // _T("") macro を使用する時に読み込むヘッダーファイル
TCHAR fnameWithPath[MAX_PATH] ;

////////////////////////////////////////////////////////////////////////////////
HINSTANCE this_hInstance ;
HWND Canvas=NULL ;
HBITMAP hBitmap=NULL ;
BITMAP bitmap ;
RECT wrct ;

void bmpLoadFunction(char *fname)
{
register HBITMAP hBitmapWk=NULL ;

// LoadImage を使ってBMPファイルを読み込む【高さがマイナス表記(上下が逆)された画像は処理できない】
if((hBitmapWk=(HBITMAP)LoadImage(this_hInstance,fname,IMAGE_BITMAP,0,0,LR_LOADFROMFILE)) == NULL ) {
MessageBox( Canvas, "BMP file load error!", "ERROR: LoadImage", MB_OK ) ;
} else { // 正しく画像が読み込まれてた時の処理
if( hBitmap ) DeleteObject(hBitmap) ; // 既に画像が読み込まれている時は、既存の画像データを破棄する
hBitmap = hBitmapWk ; // 今読み込んだ画像を処理の対象に設定
}
if( Canvas ) { // 既に画像表示ウインドウが生成されている時の処理
GetObject( hBitmap, sizeof(BITMAP), &bitmap ) ; // 画像の縦と横の大きさを得る処理
GetWindowRect( Canvas, &wrct ) ; // 画像表示ウインドウの位置を得る処理
InvalidateRect( Canvas, NULL, TRUE ) ; // 表示メモリーに強制的に書き出すおまじない
MoveWindow( Canvas, wrct.left, wrct.top, bitmap.bmWidth, bitmap.bmHeight, TRUE ) ;
} // MoveWindow を使って、画面サイズを画像サイズに変更する処理
}


void messageFromDragAndDrop( char *fnameWithPath )
{
bmpLoadFunction( _T(fnameWithPath) ) ;
}

void messageFromCommandLine( char *message )
{
bmpLoadFunction( _T(message) ) ;
}
////////////////////////////////////////////////////////////////////////////////
// ウィンドウプログラム部 // HWND は、対象ウィンドウを特定するハンドル (Window ID)
LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch( message ) {
case WM_CREATE: // CreateWindowEx(...) で WS_EX_ACCEPTFILES, を指定済み D&D が有効
Canvas = hWnd ;
if( hBitmap ) { // 画像表示ウインドウが生成される前に画像が読み込まれた時の処理
GetObject( hBitmap, sizeof(BITMAP), &bitmap ) ; // 画像の縦と横の大きさを得る処理
GetWindowRect( Canvas, &wrct ) ; // 画像表示ウインドウの位置を得る処理
InvalidateRect( Canvas, NULL, TRUE ) ; // 表示メモリーに強制的に書き出すおまじない
MoveWindow( Canvas, wrct.left, wrct.top, bitmap.bmWidth, bitmap.bmHeight, TRUE ) ;
} // MoveWindow を使って、画面サイズを画像サイズに変更する処理
break;

case WM_DROPFILES: // ドラッグアンドドロップで呼び出される
SetForegroundWindow(hWnd); // 他のスレッドよりも若干高い優先順位を割り当て
{register int i, max;
for( i=0, max=DragQueryFile( (HDROP)wParam, -1, NULL, 0 ); i<max; i++ ) {
DragQueryFile( (HDROP)wParam, i, fnameWithPath, sizeof(fnameWithPath) ) ;
messageFromDragAndDrop( fnameWithPath ) ;
}
}
DragFinish((HDROP)wParam);
break;
/* major events
case WM_LBUTTONDOWN:
break;
case WM_MOUSEMOVE:
break;
case WM_KEYDOWN: // MessageBox(hWnd, "WM_KEYDOWN", "キーイベントの発生", MB_OK);
break;
case WM_RBUTTONDOWN:
break;
*/

case WM_SIZE: // ウィンドウサイズ調整(画像が読み込まれた時に呼び出される)
PostMessage( hWnd, WM_PAINT, 0, 0 ) ;
break; // Send(If it's necessary) PostMessage(hWnd,WM_PAINT,0,0) or No break;
case WM_PAINT: // (再)描画処理、
if( hBitmap ) { // 描画用のデータを管理するメモリーに、読み込んだ画像データを転送
PAINTSTRUCT ps ;
HDC hdc, hdcd ;
hdc = BeginPaint(hWnd, &ps);
hdcd = CreateCompatibleDC(hdc);
SelectObject(hdcd, hBitmap);
BitBlt( hdc, 0, 0, bitmap.bmWidth, bitmap.bmHeight, hdcd, 0, 0, SRCCOPY) ;
DeleteDC(hdcd);
EndPaint(hWnd, &ps);
} // InvalidateRect()で表示ウインドウ内(全領域)の再描画指定により、転送したデータが表示に反映される
break;

case WM_CLOSE: // 必要な確認処理後、DestroyWindow関数を呼び出す
if( hBitmap ) DeleteObject(hBitmap) ; // 画像が読み込まれている時は、既存の画像データを破棄する
DestroyWindow( hWnd ) ;
break;
case WM_DESTROY: // ウィンドウを破棄した後に送られるメッセージ
PostQuitMessage( 0 ) ;
break;
default:
return DefWindowProc( hWnd, message, wParam, lParam ) ;
}
return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
HWND hWnd ;
WNDCLASSEX wc ;
MSG message ;
int returnedValue ; // BOOL が本来の正しい型
const char *ClassName = "Canvas", *title = "BMP file loader" ;

this_hInstance = hInstance ;
{ register int i ; // if( strlen(lpCmdLine) != 0 ) messageFromCommandLine( lpCmdLine ) ;
for( i=1; i<__argc; i++ ) messageFromCommandLine( __argv[i] ) ;
} // 作成した exe ファイルのアイコンにファイルを Drag&Drop する

// ウィンドウクラスの情報を設定
wc.cbSize = sizeof(WNDCLASSEX) ; // 構造体のサイズ
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS; // スタイルの設定
wc.lpfnWndProc = WindowProcedure; // ウィンドウプロシージャ LRESULT CALLBACK WindowProcedure(..
wc.cbClsExtra = 0; // 構造体が使用する extra メモリサイズ
wc.cbWndExtra = 0; // ウィンドウが使用する extra メモリサイズ
wc.hInstance = hInstance; // インスタンスハンドル
wc.hIcon = LoadIcon(hInstance, "PRGICON") ; // アイコン
wc.hCursor = LoadCursor(NULL, IDC_ARROW) ; // マウスカーソル
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH) ; // ウィンドウ背景
wc.lpszMenuName = NULL, // メニュー名 MAKEINTRESOURCE(..) or TEXT("..") ...
wc.lpszClassName = TEXT(ClassName) ; // ウィンドウクラス名
wc.hIconSm = LoadIcon(hInstance, "PRGICON") ; // 子アイコン

if( RegisterClassEx( &wc ) == 0 ) return 1; // ウィンドウクラスの登録

if( (hWnd = CreateWindowEx( // ウィンドウの生成
WS_EX_ACCEPTFILES, // ドラッグ&ドロップの許可 WS_EX_ACCEPTFILES
// DragAcceptFiles(hWnd, TRUE); は不要
wc.lpszClassName, // ウィンドウクラス名
TEXT(title), // タイトルバーに表示する文字列
WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU,
// ウィンドウの種類 WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, // ウィンドウを表示する位置(X座標) CW_USEDEFAULT,
CW_USEDEFAULT, // ウィンドウを表示する位置(Y座標) CW_USEDEFAULT,
256, // ウィンドウの幅 DEFAULT ⇒ MAIN_LX_SIZE,
128, // ウィンドウの高さ DEFAULT ⇒ MAIN_LY_SIZE,
NULL, // 親ウィンドウのウィンドウハンドル
NULL, // メニューハンドル
hInstance, // インスタンスハンドル
NULL // その他の作成データ
) ) == NULL ) return 1;

ShowWindow( hWnd, SW_SHOW ) ; // ウィンドウを表示
UpdateWindow( hWnd ) ; // ウィンドウの更新
// メニューの有効無効設定は、WindowProcedure の WM_CREATE で行うので、
// 現時点において、hWnd でのアクセスは失敗する。

while( (returnedValue = GetMessage(&message, NULL, 0, 0)) != 0 ) { // メインループ
if( returnedValue == -1 ) return -1; // GetMessage() が失敗(-1)なら終了する
TranslateMessage( &message ) ;
DispatchMessage( &message ) ;
}
return 0;
}

go to TopPage go to CategoryTop