// 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; }