// list0808win.cpp スレッドの応用 コンソール用グラフィックウィンドウ
// ウィンドウ側リスト
// コンパイル設定C/C++をマルチスレッドにする
#include <Windows.h>
#include <process.h>
#include "list0808.h"
void th_Proc( void *);
LRESULT CALLBACK grProc( HWND, UINT, WPARAM, LPARAM );
HINSTANCE hi;
HWND hwnd;
HDC mdc; // メモリデバイスコンテキストのハンドル
int x_size, y_size; // グラフの大きさ
int sw = 0;
IMG0 img00;
// グラフィックウィンドウの生成,メッセージループ用スレッドの起動
void gr_init(int x, int y)
{
hi = (HINSTANCE)GetWindowLong( HWND_DESKTOP, GWL_HINSTANCE );
x_size = x; y_size = y;
WNDCLASSEX wc; // 新しくつくるウインドクラス
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = grProc; // このクラスの持つウインドプロシージャ
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hi;
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wc.hIconSm = LoadIcon( NULL, IDI_WINLOGO );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
wc.lpszMenuName = NULL;
wc.lpszClassName = "GRC0"; //このクラスの名前
if(! RegisterClassEx( &wc )) return ; // ウィンドクラスの登録
img00.lpbih = (BITMAPINFOHEADER *)malloc(40);
img00.lpbi = (BITMAPINFO *)img00.lpbih;
_beginthread( th_Proc, 0, 0 ); // メッセージループのスレッドを起動
while( !sw ); // ウィンドウが表示されるのを待つ
}
// メッセージループのためのスレッド
void th_Proc( void *)
{
MSG msg;
int sm0 = GetSystemMetrics( SM_CYCAPTION );
int sm1 = GetSystemMetrics( SM_CXDLGFRAME ); // WS_OVRELAPPの場合、枠の太さは
int sm2 = GetSystemMetrics( SM_CYDLGFRAME ); // SM_C?DLGFRAMEになる
hwnd = CreateWindow( "GRC0", // クラスの名前
"Windows example",
WS_OVERLAPPED | WS_VISIBLE, // ウィンドウの属性
CW_USEDEFAULT, CW_USEDEFAULT, // 位置は指定しない
x_size + sm1 * 2, // 描画サイズからウィンドウの大きさを計算
y_size + sm0 + sm2 * 2,
HWND_DESKTOP, // 親はディスクトップ
NULL, hi, NULL );
sw = 1; // 表示されたことを知らせる
while( GetMessage( &msg, NULL, 0, 0 ) ){
TranslateMessage( &msg );
DispatchMessage( &msg );
}
free(img00.lpbih);
return ;
}
// ウィンドウプロシージャ,描画オブジェクトの準備と再描画を行う
LRESULT CALLBACK grProc( HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam )
{
static HBITMAP hbit;
switch(msg){
case WM_CREATE:{
HDC hdc = GetDC( hwnd );
// ウィンドウと同じ仮想画面を作る
mdc = CreateCompatibleDC( hdc );
hbit = CreateCompatibleBitmap( hdc, x_size, y_size );
SelectObject( mdc, hbit );
PatBlt( mdc, 0, 0, x_size, y_size, WHITENESS); // 仮想画面のクリア
ReleaseDC( hwnd, hdc );
break;
}
case WM_PAINT:{
PAINTSTRUCT ps;
BeginPaint( hwnd, &ps );
// 仮想画面からのコピー
BitBlt( ps.hdc, 0, 0, x_size, y_size, mdc, 0, 0, SRCCOPY);
EndPaint( hwnd, &ps );
break;
}
case WM_DESTROY:
DeleteDC( mdc ); // メモリデバイスコンテキストの消去
DeleteObject( hbit ); // ビットマップオブジェクトの消去
PostQuitMessage( 0 ); // スレッドを終了させる
break;
default:
return DefWindowProc( hwnd, msg, wParam, lParam );
}
return 0;
}
//////////// コンソールから利用できるグラフィック関数群
void gr_clr(void)
{
PatBlt( mdc, 0, 0, x_size, y_size, WHITENESS); // 仮想画面のクリア
return;
}
void gr_rect(int x, int y, int xx, int yy) // 仮想画面の四角描画
{
Rectangle(mdc,x,y,xx,yy);
return;
}
void gr_line(int x, int y, int xx, int yy) // 仮想画面の直線描画
{
MoveToEx( mdc, x, y, NULL);
LineTo( mdc, xx, yy);
return;
}
BYTE * gr_set_bmph(LPBITMAPINFOHEADER pbmph)
{
int i;
for(i = 0;i< 40; i++){
((BYTE *)img00.lpbih)[i] = ((BYTE *)pbmph)[i];
}
return (BYTE *)pbmph + 40;
}
void gr_cp( IMG0 *p )
{
SetDIBitsToDevice( mdc, 0, 0, // コピー先x,y座標
(p -> lpbih) -> biWidth, //DIBの幅
(p -> lpbih) -> biHeight,// DIBの高さ
0, 0, // DIBの座標
0, // 走査線
(p -> lpbih) -> biHeight, // 走査線数
p -> lpBmpData,
p -> lpbi, //BITMAPINFO:
//BITMAPINFOHEADER+RGBQUAD
DIB_RGB_COLORS );
return;
}
void gr_bmp( BYTE *p )
{
SetDIBitsToDevice( mdc, 0, 0, // コピー先x,y座標
img00.lpbih -> biWidth, //DIBの幅
img00.lpbih -> biHeight,// DIBの高さ
0, 0, // DIBの座標
0, // 走査線
img00.lpbih -> biHeight, // 走査線数
p,
img00.lpbi, //BITMAPINFO:
//BITMAPINFOHEADER+RGBQUAD
DIB_RGB_COLORS );
return;
}
void gr_active() // グラフィック画面を表に出す
{
SetForegroundWindow( hwnd );
return;
}
void gr_draw() // 仮想画面をグラフィック画面にコピー
{
HDC hdc = GetDC( hwnd );
BitBlt( hdc, 0, 0, x_size, y_size, mdc, 0, 0, SRCCOPY);
ReleaseDC( hwnd, hdc);
}
void gr_quit() // グラフィック画面の終了
{
SendMessage( hwnd, WM_CLOSE, 0, 0 );
return;
}
void gr_caption( char *p) // キャプションのセット
{
SetWindowText( hwnd, p );
}
//////////
char * file_open(void )
{
OPENFILENAME fname;
static char fn[256];
char filename[64];
memset(&fname, 0, sizeof(OPENFILENAME));
fname.lStructSize = sizeof(OPENFILENAME);
fname.hwndOwner = HWND_DESKTOP;
fname.lpstrFilter = "*.*\0*.*\0\0";
fname.nFilterIndex = 1; // 1番目のファイルフィルタを使う
fname.lpstrFile = fn; // 選択されたパス付きファイル名が格納されるアドレス
fname.nMaxFile = sizeof(fn);
fname.lpstrFileTitle = filename;
fname.nMaxFileTitle = sizeof(filename)-1;
fname.lpstrTitle = "AVIファイルを指定します";
fname.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
if( ! GetOpenFileName( &fname ) ) return NULL;
return fn;
}
BYTE * swrite( BYTE * su, int n, BYTE * fp)
{
int i;
for( i = 0; i < n ; i++ ){
*fp = *su;
fp++; su++;
}
return fp;
}