• 締切済み

[MFC]コントロールに合わせてフレームサイズ変更

OS -> Windows7 Enterprice SP1 VSバージョン -> VS2008 Professional Edition メインフレーム(CFrameWnd)内に分割ウィンドウでCFormViewを縦2つ内包した画面です。 (内1つはダミーで縦サイズが0指定) フォームビューの初期表示時にデータの有無を判定し、 データが無ければリストコントロールを非表示にして、 それ以下のコントロールを上詰めする、という処理を取っています。 その際、フレームサイズもコントロールの非表示に伴い サイズを縮小したいのですが、現状のやり方では 想定よりも縦幅が大きくなってしまいます。 以下にコードを記述します。 // CFormView void CSumpleFormView::InitFormView() { // データ取得、コントロールの位置変更は省略 // 現在のフレームサイズを取得 RECT stFrameRect; GetParentFrame()->GetWindowRect(&stFrameRect); // フレーム幅 int iFrameWidth = stFrameRect.right - stFrameRect.left; // 最下端(OKボタン)のコントロール RECT stBtnRect; m_BtnOk.GetWindowRect(&stBtnRect); // ダイアログベース単位を取得 iDlgBaseY = HIWORD(GetDialogBaseUnits()); // 余白をピクセル高さに換算する int iYPadding = MulDiv(4, iDlgBaseY, 8); // フレーム高さ // 最下端コントロールのbottom + 余白をフレーム高さとする int iFrameHeight = stBtnRect.bottom + iYPadding; // メインフレームにサイズを渡す pclMainFrame->ChangeSize(iFrameWidth, iFrameHeight); } // CFrameWnd void CSumpleFrameWnd::ChangeSize(int iWidth, int iHeight) { RECT stRect; GetWindowRect(&stRect); SetWindowPos(&CWnd::wndTop, stRect.left, stRect.top , iWidth, iHeight, SWP_SHOWWINDOW); } 余白(iYPadding)を加算せずにサイズを変更しても 最下端コントロールの下に余白が出来るので、 縦幅の設定に問題があるようです。 ですが、原因が分かりません…。 ご教授のほど、宜しくお願い致します。 また、不明な点がありましたらご質問下さい。

みんなの回答

  • davidfox
  • ベストアンサー率58% (21/36)
回答No.1

単純な事なので要所要所でトレース出力して見ればすぐに判ると思うのですが... ざっと眺めた感じでは、 SetWindowPosは座標ではなく、マニュアル通りに高さを要求するので、ちゃんと高さを計算した方がいいと思います。 何だかスクリーン座標のまま計算してあるように見えます。理屈が合えばそれでもいいのですが。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • スタティックコントロールのサイズを取得する

    VC++.NET2005で勉強しています。 例えば、mainDlgのリソースで作った、staticコントロールのサイズを、subDlgのソースから取得する方法で悩んでいます。 すでに、staticコントロールにはクラスウィザードでメンバ変数は作っており、取得する方法自体は、GetClientRect(rect) 等で取得できることはわかっています。 どのクラスからでも、特定のクラスのコントロール識別子(ID)を取得したりする事は可能でしょうか。 ご存知の方、ご教授お願い致します。

  • SetWindowPosで指定したサイズにしたい

    イメージを描画する際に、イメージのサイズ分とウインドウを構成する要素のサイズを足して、SetWindowPos でサイズを変更していますが、サイズが不足しています。 難しいです。 教えてください。お願いします。 ///////////////////////////////////////////// void CImageRectView::OnLButtonDown(UINT nFlags, CPoint point) { CImage image; image.Load("000.jpg"); CDC *imageDC=CDC::FromHandle(image.GetDC()); CDC *pDC=GetDC(); int mnuh=GetSystemMetrics(SM_CYMENU); int titleh=GetSystemMetrics(SM_CYCAPTION); CRect FrameRect,ClientRect; GetWindowRect(&FrameRect); GetClientRect(&ClientRect); int FrameWidth=(FrameRect.right-FrameRect.left)-(ClientRect.right-ClientRect.left); int FrameHeight=(FrameRect.bottom-FrameRect.top)-(ClientRect.bottom-ClientRect.top); GetParentFrame()->SetWindowPos(&wndTop,rect.left,rect.top,image.GetWidth()+FrameWidth,image.GetHeight()+FrameHeight+mnuh+titleh,SWP_NOMOVE); pDC->BitBlt(0,0,image.GetWidth(),image.GetHeight(),imageDC,0,0,SRCCOPY); ReleaseDC(pDC); ReleaseDC(imageDC); CView::OnLButtonDown(nFlags, point); } /////////////////////////////////////////////

  • CFrameWnd とCFormView3

    自分で継承したCFormViewとCFrameWndを使ったウインドウサイズを CFormViewのダイアログボックスのサイズに合わせたいのですが どうすれば良いでしょうか? 要はCFormViewをウィザードで作成したとき、ダイアログボックスのサイズに 自動で合わせてくれますがあれを実現したいのです。 現在はCFrameWndのSetWindowPosで無理やりあわせています。 具体的には グローバル変数にCRect g_DialogRectを持たせ CXXXView::OnCreateの中で GetClientRect(&g_DialogRect); クライアント領域取得 CMainFrame::OnCreateの中で SetWindowPos( &wndTop, 0, 0, g_DialogRect.Width() + 14, g_DialogRect.Height() + 80, 0 ); 14と80はメインフレームのタイトルやステータスバー、溝のサイズを埋める為適当にいれました。 (GetSystemMetricsあたりを駆使すれば取得できそうですが、) CFormViewをウィザードで作成したものは CFormViewのOnInitialUpdateの中で、 CFormView::OnInitialUpdate(); GetParentFrame()->RecalcLayout(); ResizeParentToFit(); とするみたいですが、 自分で作成したCFormViewではOnInitialUpdateを追加してブレークをはったのですが通過しないようでした。 OnCreateのタイミングでやるとResizeParentToFitで例外が発生してしまいます。 度重なる質問で恐縮ですが宜しくお願い致します。

  • ウインドウ内全体を一定時間で更新したいWinAPI

    ウインドウ内全体をWM_TIMERを使って一定時間毎に更新したいのですが、うまくいきません。資料・アドバイスを参考にここまで作ったのですが、おそらくWM_PAINTのところでリージョン領域しか更新していないのかと思います。そこでInvalidateRect( hwnd, NULL, NULL ); をウインドウ内全体をリージョンする関数、たとえはRedrawWindow などを使ってみたのですが、正しくできていないためか状況が変わりません。 毎度のことで申し訳ありませんがアドバイスお願いします。 #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); void getScreenShot(HBITMAP hBmpShot, int iX, int iY, int iWidth, int iHeight) ; /*ビットマップハンドル*/ static HBITMAP _bmpShot = 0; int _iWidth=1024, _iHeight=400; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; /* ウインドウクラス設定 */ wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "vcshot"; RegisterClass(&wndclass); /* メインウインドウ作成 */ HWND hwMain = CreateWindow("vcshot", "", WS_POPUP | WS_VISIBLE , 0,0, _iWidth, _iHeight, NULL, NULL, hInstance, NULL); ShowWindow(hwMain, iCmdShow); /* メッセージループ */ while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int)msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch (iMsg) { case WM_CREATE: { /*先に外側で作成してしまう方が得策かもしれない*/ HDC hDC = ::GetDC(0); _bmpShot = ::CreateCompatibleBitmap(hDC, _iWidth, _iHeight); ::ReleaseDC(0, hDC); /* スクリーンショット取得 */ getScreenShot(_bmpShot, 0, 0, _iWidth, _iHeight); SetTimer(hwnd , 1 , 16 , NULL); return 0; } case WM_TIMER:{ getScreenShot(_bmpShot, 0, 0, _iWidth, _iHeight); InvalidateRect( hwnd, NULL, NULL ); return 0;} case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); /* ビットマップが作成されていれば描画 */ if(_bmpShot != NULL) { BITMAP bmp; /*この関数でビットマップから、詳細を知る事が出来る*/ ::GetObject(_bmpShot, sizeof(BITMAP), &bmp); /*以下決まり文句*/ HDC _hdcShot = ::CreateCompatibleDC(0); ::SelectObject(_hdcShot, _bmpShot); BitBlt(hdc, 0, 0, _iWidth, _iHeight, _hdcShot, 0, 0, SRCCOPY); /*使い終えたら直に閉じる*/ ::DeleteDC(_hdcShot); } EndPaint(hwnd, &ps); return 0; } case WM_DESTROY : /* ビットマップが作成されていたら関連リソースを削除 */ if(_bmpShot != NULL) { /*SelectObject(_hdcShot, _bmpOld);*/ DeleteObject(_bmpShot); /*DeleteObject(_hdcShot);←よく見ると、デバイスコンテキストに対してDeleteObjectを使用しています。*/ } PostQuitMessage(0); return 0; } return DefWindowProc (hwnd, iMsg, wParam, lParam); } void getScreenShot(HBITMAP hBmpShot, int iX, int iY, int iWidth, int iHeight) { /* キャプチャサイズを保存 _iWidth = iWidth; _iHeight = iHeight; */ /* 画面のデバイスコンテキスト取得 */ HDC hdcScreen = GetDC(0); /* ビットマップ描画用デバイスコンテキスト作成 */ HDC _hdcShot = CreateCompatibleDC(hdcScreen); /* スクリーンショット保存用ビットマップ作成 */ /*_bmpShot = CreateCompatibleBitmap(hdcScreen, iWidth, iHeight);*/ /* デバイスコンテキストにビットマップを設定 */ /*_bmpOld = (HBITMAP)*/SelectObject(_hdcShot, hBmpShot); /* 画面上の領域をビットマップに描く */ BitBlt(_hdcShot, 0, 0, iWidth, iHeight, hdcScreen, 0, 0, SRCCOPY); /* 画面のデバイスコンテキスト解放 */ ReleaseDC(0, hdcScreen); /*使用したら直に閉じる*/ ::DeleteDC(_hdcShot); }

  • WinAPIでスクリーン画像を映し続けるプログラムその2

    タイマー1秒ごとに画面を更新させたいのですが、リージョンの範囲しか更新されないため、ウインドウを最上層に置いておくと、画面がかわりません。下記ソースはそれを確かめるため、タイマーで更新する画面を100×100pixlから1秒ごとに徐々に大きくしていったところ、やはりペイントが違う画面で覆った部分しかそのとおり更新されていませんでした。参考書だとこんな感じでできる気がするのですが、InvalidateRect( hwnd, NULL, TRUE );のところでウインドウ全体を更新しなければいけない範囲にするべきだと思うのですが、具体的な解決策がわかりません。 お力を貸していただけると助かります。 #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); void getScreenShot(HBITMAP hBmpShot, int iX, int iY, int iWidth, int iHeight) ; /*ビットマップハンドル*/ static HBITMAP _bmpShot = 0; int popo=100; int _iWidth=1024, _iHeight=400; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; /* ウインドウクラス設定 */ wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "vcshot"; RegisterClass(&wndclass); /* メインウインドウ作成 */ HWND hwMain = CreateWindow("vcshot", "", WS_POPUP | WS_VISIBLE , 0,0, _iWidth, _iHeight, NULL, NULL, hInstance, NULL); ShowWindow(hwMain, iCmdShow); /* メッセージループ */ while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int)msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { switch (iMsg) { case WM_CREATE: { /*先に外側で作成してしまう方が得策かもしれない*/ HDC hDC = ::GetDC(0); _bmpShot = ::CreateCompatibleBitmap(hDC, _iWidth, _iHeight); ::ReleaseDC(0, hDC); /* スクリーンショット取得 */ getScreenShot(_bmpShot, 0, 0, _iWidth, _iHeight); SetTimer(hwnd , 1 , 1000 , NULL); return 0; } case WM_TIMER:{ popo=popo+20; getScreenShot(_bmpShot, 0, 0, popo, popo); InvalidateRect( hwnd, NULL, TRUE ); return 0;} case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwnd, &ps); /* ビットマップが作成されていれば描画 */ if(_bmpShot != NULL) { BITMAP bmp; /*この関数でビットマップから、詳細を知る事が出来る*/ ::GetObject(_bmpShot, sizeof(BITMAP), &bmp); /*以下決まり文句*/ HDC _hdcShot = ::CreateCompatibleDC(0); ::SelectObject(_hdcShot, _bmpShot); BitBlt(hdc, 0, 0, _iWidth, _iHeight, _hdcShot, 0, 0, SRCCOPY); /*使い終えたら直に閉じる*/ ::DeleteDC(_hdcShot); } EndPaint(hwnd, &ps); return 0; } case WM_DESTROY : /* ビットマップが作成されていたら関連リソースを削除 */ if(_bmpShot != NULL) { /*SelectObject(_hdcShot, _bmpOld);*/ DeleteObject(_bmpShot); /*DeleteObject(_hdcShot);←よく見ると、デバイスコンテキストに対してDeleteObjectを使用しています。*/ } PostQuitMessage(0); return 0; } return DefWindowProc (hwnd, iMsg, wParam, lParam); } void getScreenShot(HBITMAP hBmpShot, int iX, int iY, int iWidth, int iHeight) { /* キャプチャサイズを保存 _iWidth = iWidth; _iHeight = iHeight; */ /* 画面のデバイスコンテキスト取得 */ HDC hdcScreen = GetDC(0); /* ビットマップ描画用デバイスコンテキスト作成 */ HDC _hdcShot = CreateCompatibleDC(hdcScreen); /* スクリーンショット保存用ビットマップ作成 */ /*_bmpShot = CreateCompatibleBitmap(hdcScreen, iWidth, iHeight);*/ /* デバイスコンテキストにビットマップを設定 */ /*_bmpOld = (HBITMAP)*/SelectObject(_hdcShot, hBmpShot); /* 画面上の領域をビットマップに描く */ BitBlt(_hdcShot, 0, 0, iWidth, iHeight, hdcScreen, 0, 0, SRCCOPY); /* 画面のデバイスコンテキスト解放 */ ReleaseDC(0, hdcScreen); /*使用したら直に閉じる*/ ::DeleteDC(_hdcShot); }

  • WinAPIでスクリーン画像を映し続けるプログラム

    通常のスクリーン画面を加工して更新し続ける、たとえば拡大ツールのようなプログラムを作るにあたりまして、 ひとまずスクリーンショットを1秒ごとに更新し続ける動作をさせたいのですが、うまくいきません。 下記のソースはWEBのサンプルをお借りし参考書を見ながら 作りました。 ずっと動かしているとメモリ使用量が上がってしまったりします。 ご指導いただけると助かります。 スクリーン画像を映し続けるプログラム/** 画面キャプチャし続ける */ #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); void getScreenShot(int iX, int iY, int iWidth, int iHeight); HBITMAP _bmpShot = NULL, _bmpOld; HDC _hdcShot = NULL; int _iWidth, _iHeight; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ MSG msg; WNDCLASS wndclass; /* ウインドウクラス設定 */ wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = "vcshot"; RegisterClass(&wndclass); /* メインウインドウ作成 */ HWND hwMain = CreateWindow("vcshot", "", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 680, NULL, NULL, hInstance, NULL); ShowWindow(hwMain, iCmdShow); /* メッセージループ */ while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int)msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; switch (iMsg) { case WM_CREATE: /* スクリーンショット取得 */ getScreenShot(0, 0, 600, 480); SetTimer(hwnd , 1 , 100 , NULL); return 0; case WM_TIMER: getScreenShot(0, 0, 600, 480); return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); /* ビットマップが作成されていれば描画 */ if (_bmpShot != NULL) { BitBlt(hdc, 0, 0, _iWidth, _iHeight, _hdcShot, 0, 0, SRCCOPY); } EndPaint(hwnd, &ps); return 0; case WM_DESTROY : /* ビットマップが作成されていたら関連リソースを削除 */ if (_bmpShot != NULL) { SelectObject(_hdcShot, _bmpOld); DeleteObject(_bmpShot); DeleteObject(_hdcShot); } PostQuitMessage(0); return 0; } return DefWindowProc (hwnd, iMsg, wParam, lParam); } void getScreenShot(int iX, int iY, int iWidth, int iHeight) { /* キャプチャサイズを保存 */ _iWidth = iWidth; _iHeight = iHeight; /* 画面のデバイスコンテキスト取得 */ HDC hdcScreen = GetDC(0); /* スクリーンショット保存用ビットマップ作成 */ _bmpShot = CreateCompatibleBitmap(hdcScreen, iWidth, iHeight); /* ビットマップ描画用デバイスコンテキスト作成 */ _hdcShot = CreateCompatibleDC(hdcScreen); /* デバイスコンテキストにビットマップを設定 */ _bmpOld = (HBITMAP)SelectObject(_hdcShot, _bmpShot); /* 画面上の領域をビットマップに描く */ BitBlt(_hdcShot, 0, 0, iWidth, iHeight, hdcScreen, 0, 0, SRCCOPY); /* 画面のデバイスコンテキスト解放 */ // ReleaseDC(NULL, hdcScreen); }

  • 突然ですが、DirectX9について質問させて頂きます。

    突然ですが、DirectX9について質問させて頂きます。 ウィンドウモードとフルスクリーンモードを切り替える プログラムを組んでいますが、なぜか、フルスクリーンモード からウィンドウモードに復帰すると画面サイズが変化してしまいます。 以下がその問題となる関数です。 void SetWindowStyle( HWND hWnd, bool g_WindowMode ) {     if( g_WindowMode )     {         SetWindowLong( hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE );         MoveWindow( hWnd, 0, 0, 0, 0, false );         SetClientSize( hWnd, WINDOW_WIDTH, WINDOW_HEIGHT ); // 以下に記載     }     else     {         SetWindowLong( hWnd, GWL_STYLE, WS_POPUP | WS_VISIBLE );         MoveWindow( hWnd, 0, 0, 800, 600, true );     } } 以下はウィンドウのサイズを再設定する関数です。 void SetClientSize( HWND hWnd, int width, int height ) {     RECT wnd_Rect, clt_Rect;     int WindowSize_Width, WindowSize_Height;     GetWindowRect( hWnd, &wnd_Rect );     GetClientRect( hWnd, &clt_Rect );     // ウィンドウのサイズを求める     WindowSize_Width = ( wnd_Rect.right - 1 ) - ( wnd_Rect.left - 1 );     WindowSize_Height = ( wnd_Rect.bottom - 1 ) - ( wnd_Rect.top - 1 );     // ウィンドウのサイズを変更     MoveWindow(    hWnd,             wnd_Rect.left,             wnd_Rect.top,             width + (WindowSize_Width-clt_Rect.right),             height + (WindowSize_Height-clt_Rect.bottom),             true     ); } SetClientSize関数はアプリ起動時に一度実行され、800x600に変更されます。 この時点では問題はありません。 しかし、フルスクリーンモード→ウィンドウモードと切り替えると、 800x576と値がおかしくなります。 結果的に800x600になる予定だったのですが…。 同じ関数を使用しているのに、なぜサイズが変化してしまうのでしょう? どなたかこの問題を解決する方法をご存知ないでしょうか? よろしくお願いします。

  • 読み込んだBMPデータの行方

    参考書を元にBMPを読み込み、 BYTE*型にデータを移して、画像処理や転送に利用できるようにしたいのですが、 どこに画像データの実体が有るのかがよくわかりません・・。 ---------- static LPBYTE lpDIB = NULL; static LPBITMAPINFO lpbiInfo; static LPDWORD lpPixel; LPBYTE lpBMP; LPBITMAPINFOHEADER lpbiBMPInfo; LPBYTE lpBMPPixel; BYTE* ppp; static int iWidth, iHeight, iLength; int iFileSize; DWORD dwOffset; int i, j; HANDLE fhBMP; DWORD dwRead; HDC hdc; PAINTSTRUCT ps; /*BMP取得*/ //ファイルオープン fhBMP = CreateFile("test.bmp", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (fhBMP == INVALID_HANDLE_VALUE) { MessageBox(NULL, "test.bmpが見つかりません。", "エラー", MB_OK); return 0; } //ファイルサイズ取得 iFileSize = GetFileSize(fhBMP, NULL); //ファイル読み込みバッファ確保 lpBMP = (LPBYTE)HeapAlloc(GetProcessHeap(), 0, iFileSize); //ファイル読み込み ReadFile(fhBMP, lpBMP, iFileSize, &dwRead, NULL); //ファイルを閉じる CloseHandle(fhBMP); //BMP内のBITMAPINFO取得 lpbiBMPInfo = (LPBITMAPINFOHEADER) (lpBMP + sizeof(BITMAPFILEHEADER)); //先頭からピクセル列までのオフセット取得 dwOffset = *(LPDWORD)(lpBMP + 10); //BMP内ピクセル列の先頭アドレス計算 lpBMPPixel = lpBMP + dwOffset; //ビットマップの大きさ取得 iWidth = lpbiBMPInfo->biWidth; iHeight = lpbiBMPInfo->biHeight; //BMPピクセル列の1ラインの長さを計算 if (iWidth % 4 == 0) { iLength = iWidth * 3; } else { iLength = iWidth * 3 + (4 - (iWidth * 3) % 4); } //DIB用バッファを確保 lpDIB = (LPBYTE)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFO) + iWidth * iHeight * 4); //DIB用ポインタ分配 lpbiInfo = (LPBITMAPINFO)lpDIB; lpPixel = (LPDWORD)(lpDIB + sizeof(BITMAPINFO)); //BITMAPINFO設定 lpbiInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpbiInfo->bmiHeader.biWidth = iWidth; lpbiInfo->bmiHeader.biHeight = iHeight; lpbiInfo->bmiHeader.biPlanes = 1; lpbiInfo->bmiHeader.biBitCount = 32; lpbiInfo->bmiHeader.biCompression = BI_RGB; //BMP内のピクセル列を32ビット化してコピー for (i = 0;i < iHeight;i++) for (j = 0;j < iWidth; j++) CopyMemory(lpPixel + j + i * iWidth, lpBMPPixel + j * 3 + i * iLength, 3); //ファイル読み込みバッファ解放 HeapFree(GetProcessHeap(), 0, lpBMP); /*描画*/ hdc = BeginPaint(hWnd, &ps); //DIBをウインドウのDCに描画 StretchDIBits(hdc, 0, 0, iWidth, iHeight, 0, 0, iWidth, iHeight, lpPixel, lpbiInfo, DIB_RGB_COLORS,SRCCOPY); EndPaint(hWnd, &ps); ---------- 描画部分のStretchDIBits()を調べて lpPixelに格納されているように思えたのですが、これはただのDWORDですし。 lpBMPPixelだとしても、描画では全く使われていないのが不可解で。 なぜこう(描画にDWORD)なっているのでしょうか? どこに画像データが有るのでしょうか?

  • GetWindowRect()が正しくない。

    Yahoo知恵袋に質問したのでですが回答がつかなかったので、こちらで再度質問します。 WindowsMobileでのGetWindowRect()の使用について分からないことがあります。 WindowsMobileもWindowsの開発も初心者の者です。 上記関数で、WM6.5の320x320Square画面のサイズが正しく得られません。 WindowsXP SP3に ・VisualStudio 2005 ・Windows MobileSDK 6 ・Windows Mobile 6.5 Professional Developer Tool Kit (JPN).msi 等をインストールした環境で、 ターゲットの画面のサイズを知りたくて、以下のように記述しました。 RECT rect_win; GetWindowRect(GetDesktopWindow(), &rect_win); 通常は正しいデータが得られるのですが、 WM6.5の320x320ドットのSquare画面の時だけ、 top:26 bottom:240 left:0 right:240 という値が返ってきます。 エミュレータでも、実機(ドコモSC-01B)でも同じ結果です。 topの26はメニューバーの分かと想像はつくのですが、bottomとrightが240となっているのが理解できません。 コーディングが間違っているのでしょうか?また、正しい値を得る別の方法があるのでしょうか? よろしくお願いします。

  • Formにエディットボックスを貼りたい

    環境はWIN98 VC++6.0 MFC SDIです。 クラスウィザードのデフォルトでSDIを作ります。 但し、6/6ページの基本クラスはCFormViewにします。 このForm上にプログラム上からエディットボックスを貼りつけるために、以下のようにしましたが、エディットボックスらしき白い四角は出来ましたが文字の入力が出来ません。 どうすればよいのでしょうか? static contID = 4000; ///////////////////////////////////////////////// int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { 略   CRect rect;   // CTestWndの上にCEditを貼り付ける   rect.top = 30;   rect.left = 30;   rect.bottom = 100;   rect.right = 100;   CEdit* edit = new CEdit();      if( edit->Create(WS_CHILD|WS_VISIBLE|WS_TABSTOP,   rect,   this,   contID++ ) != TRUE ){     throw new CException();   }   return 0; }