Cabファイルの解凍プログラムの作成におけるデバッグエラーの解決方法

このQ&Aのポイント
  • Cabファイルの解凍プログラムを作成中ですが、実行中にデバッグエラーが発生しています。
  • エラーメッセージには、関数呼び出しの呼び出し規約が一致しないという原因が考えられます。
  • 解決方法として、cab32.dllのロードや関数の呼び出し方法を確認することが重要です。
回答を見る
  • ベストアンサー

Cabの解凍プログラム

現在Cabの解凍をするプログラムを作っています。 Cabファイル内のファイル数を取得するために、 int WINAPI CabGetFileCount(LPCSTR szArcFile); というAPIを使おうとしているのですが、 実行中に、デバッグエラーが出ます。 エラーメッセージ The value ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention pointer declared with a different calling convention. ソースは以下のものです。 typedef bool (*TFUNC)(LPCSTR); void 関数名(HWND hWnd) { HINSTANCE hCab=NULL; //cab32.dllのインスタンスハンドル TFUNC DllFunction; int FileCount; //cab32.dllのロード hCab = LoadLibrary("cab32.dll"); if(hCab == NULL) { MessageBox(hWnd,"cab32.dllがありません。","エラー",MB_OK); return; } DllFunction=(TFUNC)GetProcAddress(hCab,"CabGetFileCount"); FileCount = (*DllFunction)("test.cab"); FreeLibrary(hCab); } (DLL使用テストのソース) コンパイラーは"VC++6.0" OSはWin2Kになります。 わかるかたよろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.3

>それは >"typedef"にということでしょうか? >そこにWINAPIをつけるとコンパイル時にエラーが出ることを確認しています。 (^^;; #1の方の定義の仕方が間違ってるんですけど。 正しくは typedef int (WINAPI * TFUNC)(LPCSTR); と括弧の中に入れる必要があります。 また、"WORD WINAPI CabGetVersion(VOID);" は利用することができるのですが、これの場合はWINAPIは不要で動きました。 WINAPIというか__stdcallは、引数のスタックへのつみ方を定義するキーワードです。なので、voidの場合は動いたんでしょう。

Yukidaruma0824
質問者

お礼

無事解決できました!ありがとうございました!

その他の回答 (2)

  • taka_tetsu
  • ベストアンサー率65% (1020/1553)
回答No.2

ちゃんとWINAPIもつけました?

Yukidaruma0824
質問者

補足

それは "typedef"にということでしょうか? そこにWINAPIをつけるとコンパイル時にエラーが出ることを確認しています。 また、"WORD WINAPI CabGetVersion(VOID);" は利用することができるのですが、これの場合はWINAPIは不要で動きました。

  • kmb01
  • ベストアンサー率45% (63/138)
回答No.1

int WINAPI CabGetFileCount(LPCSTR szArcFile); と宣言されているのだから typedef int WINAPI (*TFUNC)(LPCSTR); では?

Yukidaruma0824
質問者

補足

失礼しました。他のCABのSDKに入ってるAPIを確かめたのがそのままになってました。 int に直しても、状態はかわらずです。

関連するQ&A

  • エラー内容について

    お世話になっております。 現在、VC++6.0にてアプリを開発中です。 そこで、下記エラーが発生し、処理がうまく行きません。 エラーの内容と、対策をお教え下さい。 [エラー内容] Debug Error! Program:xxxxxxxxx.exe Module: File:i386\chkesp.c Line:42 The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention. (Press Retry to debug the application) エラー発生の場所は、GetProcAddressで、DLLの関数のアドレスを取得し、その関数をコールした結果で起こっています。 DLL内部にログ出力を入れた結果、DLLの関数自体は正常終了しています。 DLLの関数を取得している部分は下記の通りです。 typedef int (APIENTRY *LPGetRouteList)(WORD wdIn1, WORD wdIn2, WORD wdin3);   ・   ・   ・ LPGetRouteList lpGetRouteList;   ・   ・   ・ lpGetRouteList = (LPGetRouteList)GetProcAddress(hHandle,"GetRouteList); 関数を使用している部分は、下記の通りです。 int iRet = 0;   ・   ・   ・ iRet = lpGetRouteList(wdA, wdB, wdC); <- ここでエラーが発生 DLLの関数は以下の通りです。 extern WORD APIENTRY GetRouteList(WORD wdIn1, WORD wdIn2, WORD wdIn3) { WORD wdRet = 0;   ・   ・   ・  return(wdRet); } 以上、長文で見づらいと思われますが、なにとぞ宜しくお願いします。

  • 自作DirectShow Filterのinterface定義

    DirectShow Filterを自作しGraphEdit上で動作することを確認しました。 しかしC++プログラム上から独自定義のメソッドを呼び出すと 呼び出し元と先で呼び出し規約が異なるというエラーが出てしまいます。 定義は DEFINE_GUID(CLSID_MyClass, <<適当なGUID1>>); DEFINE_GUID(IID_IMyClass, <<適当なGUID2>>); MIDL_INTERFACE("<<適当なGUID2>>") IMyClass : public IUnknown {  STDMETHOD(myMethod)(void) PURE; }; class CMyClass : public CTransInPlaceFilter {  CMyClass ::CMyClass (IUnknown * pOuter, HRESULT * phr, BOOL ModifiesData);  CMyClass ::~CMyClass (); public:  static CUnknown *WINAPI CMyClass::CreateInstance(LPUNKNOWN punk, HRESULT *phr);  DECLARE_IUNKNOWN;  STDMETHODIMP CMyClass::myMethod(void){return S_OK;}; } 呼び出し元では DEFINE_GUID(CLSID_MyClass, <<適当なGUID1>>); DEFINE_GUID(IID_IMyClass, <<適当なGUID2>>); MIDL_INTERFACE("<<適当なGUID2>>") IMyClass : public IUnknown {  STDMETHOD(myMethod)(void) PURE; }; int main() {  CoInitialize(NULL);  IMyClass pMyClass;  CoCreateInstance(   CLSID_MyClass,   NULL,   CLSCTX_INPROC,   IID_IMyClass,   (LPVOID *)&pMyClass  );  pMyClass->myMethod();←ここでエラー  ・  ・  (略)  ・  ・ } エラーメッセージは Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention. です。 どちらも__stdcallになってるはずなんですが… 原因が分かる方おられましたらよろしくお願いいたします。

  • DLLをGetProcAddress()で実行できない。

    dllの操作の練習をしております。以下のソースのどこがおかしいのでしょうか? add.dllの内容は単にa+bの結果をメッセージボックスに表示させるだけの処理です。add.lib(インポートライブラリ)をリンクさせればうまく動きます。 しかし、GetProcAddress()を使って明示的にdllを呼び出そうとすると、コンパイルエラーで ADD(hWnd,5,5); の行に 「int (__stdcall *)(void)' : 実引数が多すぎます。」 となります。このメッセージの意味もわかりません。 以下のソースのどこがおかしいのでしょうか?コンパイラはVC++6.0でOSはWin2000です。 #include<windows.h> void CALLBACK ADD(HWND hwnd,int a, int b); //ウィンドウプロージャ(ここは別に普通) LRESULT CALLBACK WndProc(HWND hWnd , UINT msg , WPARAM wp , LPARAM lp) { switch (msg) { case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hWnd , msg , wp , lp); } int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance , PSTR lpCmdLine , int nCmdShow) { static FARPROC ADD;  //あやしい HWND hWnd; MSG msg; WNDCLASS winc;     //ウィンドウを作る処理 //~(省略)~ /****明示的にdllを呼び出す****/ ADD = GetProcAddress( LoadLibrary(TEXT("add.dll")) , TEXT("ADD")); ADD(hWnd,5,5); /****************************/ while (GetMessage(&msg , NULL , 0 , 0 )) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } お願いします。

  • LoadImageを使ったアイコンファイルの読み込みの前処理

    いつも、お世話になっております。 小生、只今WindowsXPSP3上にてC言語とWin32APIを使い、BCC5.5.1でコンパイルし、Windowsプログラミングを勉強しています。 アイコンの読み込みについて質問なのですが、 WndProc関数内のWM_CREATEメッセージにて、アイコンを読み込みたいのですが、ビットマップを読み込む時の様に、CreateCompatibleDCを使い、 メモリデバイスコンテキストを作成する必要があるのでしょうか?? 以下にコードを記します。 お忙しい中、大変、申し訳ございませんが。 先輩方、アドバイスの方、宜しくお願いします。 #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); ATOM InitApp(HINSTANCE, LPCSTR); BOOL InitInstance(HINSTANCE, int, LPCSTR); int WINAPI WinMain( HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { MSG msg; BOOL bRet; LPCSTR szClassName = "アイコンを読み込む"; if(!InitApp(hCurInst, szClassName)){ return FALSE; } if(!InitInstance(hCurInst, nCmdShow, szClassName)){ return FALSE; } while((bRet = GetMessage(&msg, NULL, 0, 0)) != 0){ if(bRet == -1){ MessageBox(NULL, "GetMessage Error", "Error", MB_OK); break; } else{ TranslateMessage(&msg); DispatchMessage(&msg); } } return (int)msg.wParam; } //ウィンドウクラスの登録 ATOM InitApp(HINSTANCE hInst, LPCSTR szClassName) { WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; wc.hIcon = (HICON)LoadImage( NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hCursor = (HCURSOR)LoadImage( NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = (LPCSTR)szClassName; wc.hIconSm = (HICON)LoadImage( NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); return (RegisterClassEx(&wc)); } //ウィンドウの生成 BOOL InitInstance(HINSTANCE hInst, int nCmdShow, LPCSTR szClassName) { HWND hWnd; hWnd = CreateWindow( szClassName, "Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, NULL); if(!hWnd){ return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } //ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { static HICON hIcon; switch(msg){ case WM_CREATE: //ここにメモリデバイスコンテキストを取得の処理が必要?? hIcon = (HICON)LoadImage( NULL, "Linux.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE); if(hIcon == NULL){ MessageBox(hWnd, "It failed in reading the icon file.", "Error", MB_OK | MB_ICONWARNING); return 0; } break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; }

  • ウィンドウサイズを変更しても、サイズが描画されない。

    小生、只今C言語とWin32APIでアプリを作成しています。 そこで質問なのですが、以下のコードを実行しても、 ウィンドウにウィンドウサイズが描画されません。 例 幅0 : 高さ0 と描画され、ウィンドウのサイズを変更しても、 幅、高さどちらとも、0のままです。 どうか、お分かりになる諸先輩方、ご教授の方宜しくお願いします。 ※尚、文字数の関係もある為、多少削ってあります。 #include <windows.h> #define BUFSIZ 1024 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); ATOM InitApp(HINSTANCE, LPCSTR); BOOL InitInstance(HINSTANCE, int, LPCSTR); int WINAPI WinMain( HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { MSG msg; BOOL bRet; LPCSTR szClassName = "WindowSizeAndOneButton"; if(!InitApp(hCurInst, szClassName)){ return FALSE; } if(!InitInstance(hCurInst, nCmdShow, szClassName)){ return FALSE; } while((bRet = GetMessage(&msg, NULL, 0, 0)) != 0){ if(bRet == -1){ MessageBox(NULL, "GetMessage Error", "Error", MB_OK); break; } else{ TranslateMessage(&msg); DispatchMessage(&msg); } } return (int)msg.wParam; } ATOM InitApp(HINSTANCE hInst, LPCSTR szClassName) { WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; wc.hIcon = (HICON)LoadImage( NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hCursor = (HCURSOR)LoadImage( NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = (LPCSTR)szClassName; wc.hIconSm = (HICON)LoadImage( NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); return (RegisterClassEx(&wc)); } BOOL InitInstance(HINSTANCE hInst, int nCmdShow, LPCSTR szClassName) { HWND hWnd; hWnd = CreateWindow( szClassName, "Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, NULL); if(!hWnd){ return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } //ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { HDC hdc; PAINTSTRUCT ps; static int width, height; static TCHAR buf[BUFSIZ]; width = height = 0; switch(msg){ case WM_DESTROY: PostQuitMessage(0); return 0; case WM_SIZE: width = LOWORD(lp); height = HIWORD(lp); return 0; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); wsprintf(buf, "幅 = %d : 高さ = %d", width, height); TextOut(hdc, 10, 10, buf, lstrlen(buf)); EndPaint(hWnd, &ps); } return DefWindowProc(hWnd, msg, wp, lp); }

  • C言語でWin32APIを使い、子ウィンドウを表示したいのですが。。。

    いつもお世話になっております。 小生、只今C言語とWin32APIを使い、WindowsXPSP3上で、BCC5.5.1を使用し、Windowsプログラミングを勉強しています。 今回、子供ウィンドウを表示しようとしたのですが、 下記のコードをコンパイルしても、子供ウィンドウが表示されません。 大変、申し訳ございませんが、先輩方、アドバイス宜しくお願いします。 /* 子供ウィンドウを作成 */ #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); ATOM InitApp(HINSTANCE, LPCSTR); BOOL InitInstance(HINSTANCE, int, LPCSTR); int WINAPI WinMain( HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { MSG msg; BOOL bRet; LPCSTR szClassName = "ChildWindow"; if(!InitApp(hCurInst, szClassName)){ return FALSE; } if(!InitInstance(hCurInst, nCmdShow, szClassName)){ return FALSE; } while((bRet = GetMessage(&msg, NULL, 0, 0)) != 0){ if(bRet == -1){ MessageBox(NULL, "GetMessage Error", "Error", MB_OK); break; } else{ TranslateMessage(&msg); DispatchMessage(&msg); } } return (int)msg.wParam; } //ウィンドウクラスの登録 ATOM InitApp(HINSTANCE hInst, LPCSTR szClassName) { WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; wc.hIcon = (HICON)LoadImage( NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hCursor = (HCURSOR)LoadImage( NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = (LPCSTR)szClassName; wc.hIconSm = (HICON)LoadImage( NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); return (RegisterClassEx(&wc)); } //ウィンドウの生成 BOOL InitInstance(HINSTANCE hInst, int nCmdShow, LPCSTR szClassName) { HWND hWnd; hWnd = CreateWindow( szClassName, "Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInst, NULL); if(!hWnd){ return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } //ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { static HWND hWndChild; HINSTANCE hInst; switch(msg){ case WM_CREATE: hInst = ((LPCREATESTRUCT)lp)->hInstance; hWndChild = CreateWindow( "Child", "子供ウィンドウ", WS_CHILD | WS_SYSMENU | WS_THICKFRAME | WS_CAPTION | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 200, 100, hWnd, 0, hInst, NULL); ShowWindow(hWndChild, SW_SHOW); UpdateWindow(hWndChild); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; }

  • Win32APIにて、ウィンドウ全体をドラッグして動かしたいのですが。

    こんにちは。 いつもお世話になっております。 小生、只今WindowsXPSP3上で、C言語とWin32APIを使用し、BCC5.5.1でコンパイルしながら、Windowsプログラミングを勉強しています。 度々、質問させて頂き、その都度回答を頂戴し、誠に恐縮ではあるのですが、今回も質問させて下さい。 下記のコードをコンパイルすると、タイトルバーをドラッグして移動する事は出来るのですが、ウィンドウ全体(クライアント領域も含めて)移動するにはどのようにすればいいのでしょうか?? /* ウィンドウ表示 */ #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); ATOM InitApp(HINSTANCE, LPCSTR); BOOL InitInstance(HINSTANCE, int, LPCSTR); int WINAPI WinMain( HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { MSG msg; BOOL bRet; LPCSTR szClassName = "Window"; if(!InitApp(hCurInst, szClassName)){ return FALSE; } if(!InitInstance(hCurInst, nCmdShow, szClassName)){ return FALSE; } while((bRet = GetMessage(&msg, NULL, 0, 0)) != 0){ if(bRet == -1){ MessageBox(NULL, "GetMessage Error", "Error", MB_OK); break; } else{ TranslateMessage(&msg); DispatchMessage(&msg); } } return (int)msg.wParam; } //ウィンドウクラスの登録 ATOM InitApp(HINSTANCE hInst, LPCSTR szClassName) { WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; wc.hIcon = (HICON)LoadImage( NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hCursor = (HCURSOR)LoadImage( NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = (LPCSTR)szClassName; wc.hIconSm = (HICON)LoadImage( NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); return (RegisterClassEx(&wc)); } //ウィンドウの生成 BOOL InitInstance(HINSTANCE hInst, int nCmdShow, LPCSTR szClassName) { HWND hWnd; hWnd = CreateWindow( szClassName, "Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 200, 200, NULL, NULL, hInst, NULL); if(!hWnd){ return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } //ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { switch(msg){ case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; } お忙しい中申し訳ございませんが、 先輩方、アドバイス宜しくお願い致します。

  • LoadImageを使用し、タイトルバーのアイコンを表示したいのですが。

    こんにちは。 いつもお世話になっております。 小生、只今WindowsXPSP3上で、C言語とWin32APIを使用し、BCC5.5.1でコンパイルしながら、Windowsプログラミングを勉強しています。 度々、質問させて頂き、その都度回答を頂戴し、誠に恐縮ではあるのですが、今回も質問させて下さい。 内容はLoadImage関数を利用した、タイトルバーのアイコン表示です。 以下のコードを試しても、タイトルバーにアイコンが表示されません。 かといって、色々なサイトを見、LoadIconを使用しようとして、MSDNを調べると"この関数は、LoadImage 関数に取って代わられました。"と表記されています。 #if 1 /* タイトルバーにアイコン表示 */ #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); ATOM InitApp(HINSTANCE, LPCSTR); BOOL InitInstance(HINSTANCE, int, LPCSTR); int WINAPI WinMain( HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { MSG msg; BOOL bRet; LPCSTR szClassName = "TitleBarIcon"; if(!InitApp(hCurInst, szClassName)){ return FALSE; } if(!InitInstance(hCurInst, nCmdShow, szClassName)){ return FALSE; } while((bRet = GetMessage(&msg, NULL, 0, 0)) != 0){ if(bRet == -1){ MessageBox(NULL, "GetMessage Error", "Error", MB_OK); break; } else{ TranslateMessage(&msg); DispatchMessage(&msg); } } return (int)msg.wParam; } //ウィンドウクラスの登録 ATOM InitApp(HINSTANCE hInst, LPCSTR szClassName) { WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; wc.hIcon = (HICON)LoadImage( NULL, "Linux.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE | LR_SHARED); wc.hCursor = (HCURSOR)LoadImage( NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = (LPCSTR)szClassName; wc.hIconSm = (HICON)LoadImage( NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); return (RegisterClassEx(&wc)); } //ウィンドウの生成 BOOL InitInstance(HINSTANCE hInst, int nCmdShow, LPCSTR szClassName) { HWND hWnd; hWnd = CreateWindow( szClassName, "TitleBarIcon", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 200, 200, NULL, NULL, hInst, NULL); if(!hWnd){ return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } //ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { switch(msg){ case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; } お忙しい中、申し訳ございませんが、 先輩方、アドバイス宜しくお願い致します。 ちなみに読み込んでいるアイコンのサイズは幅、高さとも32ピクセルです。

  • CreateDCA、CreateDCWのパラメータ

    HDC CreateDC(LPCTSTR lpszDriver, LPCTSTR lpszDevice, LPCTSTR lpszOutPut, CONST DEVMODE *lpInitData)にはUnicode版とANSI版が実装されます よってCreateDCAでは HDC CreateDCA(PCTSTR lpszDriver, PCTSTR lpszDevice, PCTSTR lpszOutPut, CONST DEVMODE *lpInitData) CreateDCWでは HDC CreateDCW(LCPWSTR lpszDriver, LCPWSTR lpszDevice, LCPWSTR lpszOutPut, CONST DEVMODE *lpInitData) と定義されているのだと思い、上記の形式で呼び出しましたがエラーとなってしました Run_Time check Failure #0- The Value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling conversion with a function pointer declared with a different calling conversion. なぜCreateDCではなくCreateDCAとCrateDCWを直接呼び出すような面倒なことをしているかというと、APIフックでCreateDCを引っ掛けたいのです CreateDCはCreateDCA、CreateDCWになってしまうのでCreateDCではフック出来ません そこでCreateDCA、CreateDCWでフックして当方の処理を行い、その後で本来のCreateDCA、CreateDCWを呼び出しております ところが呼出し方が悪いらしく上記の英文エラーが出てしまいます CreateDCA、CreateDCWで検索したのですが適当な資料が見当たりません 目下のところ手も足も出ません CreateDCA、CreateDCWのパラメータ指定法(多分エラーの原因だろうと思っていますので・・・)をご存知でしたらご指導願います

  • Win32APIでウィンドウを中央に配置する関数の仕組みを教えてください。

    こんにちは。 いつもお世話になっております。 小生、只今WindowsXPSP3上で、C言語とWin32APIを使用し、BCC5.5.1でコンパイルしながら、Windowsプログラミングを勉強しています。 度々、質問させて頂き、その都度回答を頂戴し、誠に恐縮ではあるのですが、今回も質問させて下さい。 現在「猫でもわかるWindowsプログラミング第2版」の第14章"デスクトップアクセサリを作る"の箇所で、以下のコードのWM_CREATEメッセージで呼び出す、MyMoveCenterという関数の仕組みが中々理解出来ないでいます。 /* ウィンドウを画面中央に表示 */ #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); ATOM InitApp(HINSTANCE, LPCSTR); BOOL InitInstance(HINSTANCE, int, LPCSTR); void MyMoveCenter(HWND); int WINAPI WinMain( HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { MSG msg; BOOL bRet; LPCSTR szClassName = "WindowCenter"; if(!InitApp(hCurInst, szClassName)){ return FALSE; } if(!InitInstance(hCurInst, nCmdShow, szClassName)){ return FALSE; } while((bRet = GetMessage(&msg, NULL, 0, 0)) != 0){ if(bRet == -1){ MessageBox(NULL, "GetMessage Error", "Error", MB_OK); break; } else{ TranslateMessage(&msg); DispatchMessage(&msg); } } return (int)msg.wParam; } //ウィンドウクラスの登録 ATOM InitApp(HINSTANCE hInst, LPCSTR szClassName) { WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInst; wc.hIcon = (HICON)LoadImage( NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hCursor = (HCURSOR)LoadImage( NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = (LPCSTR)szClassName; wc.hIconSm = (HICON)LoadImage( NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED); return (RegisterClassEx(&wc)); } //ウィンドウの生成 BOOL InitInstance(HINSTANCE hInst, int nCmdShow, LPCSTR szClassName) { HWND hWnd; hWnd = CreateWindow( szClassName, "Window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 200, 200, NULL, NULL, hInst, NULL); if(!hWnd){ return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } //ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { switch(msg){ case WM_CREATE: MyMoveCenter(hWnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0; } //ウィンドウを中央に配置 void MyMoveCenter(HWND hWnd) { //スクリーンの幅、高さ、座標 int w, h, x, y; RECT rc; w = GetSystemMetrics(SM_CXSCREEN); h = GetSystemMetrics(SM_CYSCREEN); GetWindowRect(hWnd, &rc); x = (w - (rc.right - rc.left)) / 2; y = (h - (rc.bottom - rc.top)) / 2; MoveWindow(hWnd, x, y, (rc.right - rc.left), (rc.bottom - rc.top), TRUE); } 書籍には図を描けば、一目瞭然という風に書いてあり、図を描けば、 なるほどとうなずけるのですが、どうして、下図のような計算をしたら中央の座標が取得できるのかが、いまいちピンとこないのです。 x = (w - (rc.right - rc.left)) / 2; y = (h - (rc.bottom - rc.top)) / 2; これは座標の数式にある公式の様なものでしょうか?? お忙しい中申し訳ございませんが、先輩方、アドバイスの方、宜しくお願いします。

専門家に質問してみよう