ホーム > カテゴリ > C/C++ >

自己解凍書庫(SFX)を作成する-CAB編(C/C++版)

自己解凍書庫(SFX)を作成する-CAB編のサンプルです。

サンプルの実行画面

ソースコード

[Sample86.c]

//--------------------------------------------------------------------------------------
//  ■自己解凍書庫(SFX)を作成する-CAB編■ Sample NO.86
//
//--------------------------------------------------------------------------------------

//
//・このサンプルには「cab32.dll」が必要です。DLLがない場合はhttp://www.csdinc.co.jp/archiver/から取得して下さい。
//

#include <windows.h>

HWND hEdit;

//コマンドID
#define ID_EDIT 1501

//リソースID
#define ID_MENU 100
 #define ID_SUBMENU 101
  
//Cab()API
typedef int (*PCab)(const HWND hwnd, LPCSTR szCmdLine,LPSTR szOutput, const DWORD dwSize);

int OpenDiaog(HWND hwnd,LPCSTR Filter,char *FileName,DWORD Flags);
int SaveDiaog(HWND hwnd,LPCSTR Filter,char *FileName,DWORD Flags);

//ウインドウを中央にする為にX座標(LEFT)とY座標(TOP)算出するマクロ
#define ScreenCenterX(Width) ((0)<((int)((GetSystemMetrics(SM_CXSCREEN)- Width) / 2)) ? ((int)((GetSystemMetrics(SM_CXSCREEN)- Width) / 2)) :(0))
#define ScreenCenterY(Height) ((0)<((int)((GetSystemMetrics(SM_CYSCREEN)- Height) / 2)) ? ((int)((GetSystemMetrics(SM_CYSCREEN)- Height) / 2)) :(0))

//いつものプロシージャ
HWND CreateMainWindow(int Width,int Height,LPCTSTR Caption,HINSTANCE hInstance,int nCmdShow,WNDPROC lpfnWndProc, DWORD dwstyle,DWORD dwExstyle,LPCTSTR MenuID,HICON hIcon);
int  WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow);
LRESULT CALLBACK WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam);


//------------------------------------------------------
//■関数 OpenDiaog
//■用途 「ファイルを開く」ダイアログを表示する
//■引数
//        hwnd       ...親ウインドウのハンドル
//        Filter     ...フィルター
//        FileName   ...ファイルのフルパス名(戻り値)
//        Flags      ...ダイアログのフラグ
//■戻り値
//      ファイルを選択  true   
//------------------------------------------------------
int OpenDiaog(HWND hwnd,LPCSTR Filter,char *FileName,DWORD Flags)
{
   OPENFILENAME OFN; 

   ZeroMemory(&OFN,sizeof(OPENFILENAME));
   OFN.lStructSize = sizeof(OPENFILENAME); 
   OFN.hwndOwner = hwnd;
   OFN.lpstrFilter =Filter;
   OFN.lpstrFile =FileName;  
   OFN.nMaxFile = MAX_PATH*2;
   OFN.Flags = Flags;    
   OFN.lpstrTitle = "ファイルを開く";
   return (GetOpenFileName(&OFN));
}

//------------------------------------------------------
//■関数 SaveDiaog
//■用途 「名前を付けて保存」ダイアログを表示する
//■引数
//        hwnd       ...親ウインドウのハンドル
//        Filter     ...フィルター
//        FileName   ...ファイルのフルパス名(戻り値)
//        Flags      ...ダイアログのフラグ
//■戻り値
//      ファイルを選択 true   
//------------------------------------------------------
int SaveDiaog(HWND hwnd,LPCSTR Filter,char *FileName,DWORD Flags)
{
   OPENFILENAME OFN; 

   ZeroMemory(&OFN,sizeof(OPENFILENAME));
   OFN.lStructSize = sizeof(OPENFILENAME); 
   OFN.hwndOwner = hwnd;
   OFN.lpstrFilter =Filter;
   OFN.lpstrFile =FileName;  
   OFN.nMaxFile = MAX_PATH*2;
   OFN.Flags = Flags;    
   OFN.lpstrTitle = "名前を付けて保存";
   return (GetSaveFileName(&OFN));
}

//------------------------------------------------------
//■関数 CreateMainWindow
//■用途 メインウインドウを作成する
//■引数
//  Width       ...ウインドウの横幅
//  Height      ...ウインドウの縦幅
//  Caption     ...タイトル名
//  hInstance   ...インスタンスハンドル
//  nCmdShow    ...ウインドウの表示形態
//  lpfnWndProc ...コールバックプロシージャ
//  dwstyle     ...ウインドウスタイル
//  dwExstyle   ...拡張ウインドウスタイル
//  MenuID      ...メニューのID
//  hIcon       ...アイコン
//■戻り値
//  ウインドウのハンドル
//------------------------------------------------------
HWND CreateMainWindow(int Width,int Height,LPCTSTR Caption,HINSTANCE hInstance,int nCmdShow,WNDPROC lpfnWndProc, DWORD dwstyle,DWORD dwExstyle,LPCTSTR MenuID,HICON hIcon)
{
    HWND hWnd;         //メインウインドウのハンドル
    WNDCLASS myClass;  //WNDCLASS構造体
    
    //WNDCLASS構造体を0で初期化
    ZeroMemory(&myClass,sizeof(WNDCLASS));
 
//--->WNDCLASS構造体の設定&ウインドウクラスの登録

    myClass.style =CS_HREDRAW | CS_VREDRAW;       //ウインドウスタイルを設定 
    myClass.lpfnWndProc   = lpfnWndProc;          //コールバックプロシージャへのポインタ
    myClass.hInstance=hInstance;                  //インスタンスハンドルを設定
    myClass.hCursor=LoadCursor(NULL, IDC_ARROW);  //カーソルの設定(Windows標準リソースを使用)  
    myClass.hbrBackground=(HBRUSH)COLOR_WINDOW;   //ウインドウの背景を設定(デフォルトカラー)
    myClass.lpszClassName="TForm";                //クラス名の設定(Borland Delphi風)  
    myClass.hIcon =hIcon;                         //アイコンの指定
    myClass.lpszMenuName=MenuID;                  //メニューの設定

    //ウィンドウ クラスを登録
    RegisterClass(&myClass); 
    
//--->ウインドウの作成&表示
   
  //メインウインドウの生成
  hWnd = CreateWindowEx(
           dwExstyle,            //拡張ウインドウスタイル
           "TForm",              //登録されたクラス名のアドレス 
           Caption,              //ウインドウ名
           dwstyle,              //ウインドウスタイルを設定
           ScreenCenterX(Width), //X座標の位置設定
           ScreenCenterY(Height),//Y座標の位置設定
           Width,                //横幅を設定
           Height,               //縦幅を設定
           NULL,                 //親ウインドウを設定
           NULL,                 //メニューを設定
           hInstance,            //インスタンスを識別
           NULL);                //作成したウインドウに渡すデータへのポインタ
 
  //ウインドウの表示(表示方法はnCmdShowに従う)
  ShowWindow(hWnd, nCmdShow);
  return(hWnd);
}

//--------------------------------------------------------
//■関数 WinMain
//■用途 メインの関数 
//■引数
// hInstance    ...現在のインスタンスのハンドル
// hPrevInstance...以前のインスタンスのハンドル
// pszCmdLine   ...コマンド ラインのアドレス
// nCmdShow     ...ウィンドウの表示状態
//--------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{    
   MSG    msg;

   CreateMainWindow(400,400,"自己解凍書庫(SFX)を作成する-CAB編",hInstance,nCmdShow,(WNDPROC)WindowProc,
       WS_OVERLAPPEDWINDOW,WS_EX_CONTROLPARENT | WS_EX_WINDOWEDGE,MAKEINTRESOURCE(ID_MENU),LoadIcon(NULL,MAKEINTRESOURCE(IDI_APPLICATION)));
  
  //送られてくるメッセージを翻訳してプロシージャに渡す  
  while (GetMessage(&msg, NULL, 0, 0)) 
   {
      TranslateMessage(&msg); 
      DispatchMessage(&msg);   
  } 
 return (msg.wParam);
}

//------------------------------------------------------
// ■関数 WindowProc
// ■用途 メインウインドウに送られるメッセージを処理
// ■引数
//        hwnd    ...ウインドウのハンドル
//        uMsg    ...メッセージID
//        wParam  ...第1メッセージ パラメータ    
//        lParam  ...第2メッセージ パラメータ
//------------------------------------------------------
LRESULT CALLBACK  WindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{   
 HINSTANCE  hCab=NULL;         //cab32.dllのインスタンスハンドル
 PCab       Cab=NULL;          //Cab()APIへのポインタ
 int        Result;
 char       buffer[1024],SrcName[MAX_PATH*2],szCmdLine[1024],destName[MAX_PATH*2];

  switch (uMsg)
    {
       case WM_CREATE:
         hEdit= CreateWindowEx(WS_EX_CLIENTEDGE,"EDIT","",ES_AUTOVSCROLL |ES_WANTRETURN |ES_MULTILINE|ES_AUTOHSCROLL |WS_VSCROLL|WS_HSCROLL|WS_CHILD|WS_VISIBLE,0,20,400,380,hwnd,(HMENU)ID_EDIT,(HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE),NULL);    
        
         break;
    case WM_COMMAND:
           if (LOWORD(wParam)==ID_SUBMENU) 
          {
            //cab32.dllのロード
            hCab = LoadLibrary("cab32.dll");
            if (hCab!=NULL)
            {  
                 //cab()APIの呼び出し
                Cab = (PCab)GetProcAddress(hCab, "Cab");                
                 if (Cab!=NULL)
                {
                   //ファイルを開く
                      ZeroMemory(SrcName,MAX_PATH*2);
                   if (OpenDiaog(hwnd,"CAB(*.CAB)\0 *.cab\0\0",
                        SrcName,OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY))
                   {                                  
                       //ファイルを保存する
                       ZeroMemory(destName,MAX_PATH*2);
                        if (SaveDiaog(hwnd,"eXe(*.exe) *.exe",
                         destName,OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT))
                       {                         
                           //コマンドライン文字列制御
                           strcpy(szCmdLine, "-f ");  
                           strcat(szCmdLine, "\"");
                           strcat(szCmdLine, SrcName);  
                           strcat(szCmdLine, "\"");
                           strcat(szCmdLine, " ");   
                           strcat(szCmdLine, "\"");
                           strcat(szCmdLine, destName); 
                           strcat(szCmdLine, "\"");
                           //自己解凍書庫(SFX)を作成する
                           Result=(*Cab)(NULL,szCmdLine,buffer,1024);    
                           if (Result==0)
                             SendMessage(hEdit, WM_SETTEXT, 0, (LPARAM)buffer);
                           else
                             SendMessage(hEdit, WM_SETTEXT, 0, (LPARAM)"何らかの処理でエラーが発生しました。");
                       }
                   }
                }
                else MessageBox(hwnd,"Cab()APIが存在しません。DLLがぶっ壊れています。","エラー",MB_OK);
              FreeLibrary(hCab);
            }
            else MessageBox(hwnd,"cab32.dllがありません。","エラー",MB_OK);
           }
         
               
          break;
    case WM_SIZE:
             MoveWindow(hEdit,0,0,LOWORD(lParam),HIWORD(lParam),TRUE);
             break;
      case WM_DESTROY:
                  PostQuitMessage(0);
                  break;
      //その他のメッセージはWindowsに任せる
      default:return(DefWindowProc(hwnd, uMsg, wParam, lParam)); 
    }
    return (0);
}

ソースコード一式のダウンロード

capi_sample86.zip 3,594 バイト

動作環境

このサンプルは 「Windows98」及び「Microsoft Visual C++5.0」「Borland C++ Compiler 5.5」で確認しております。環境が異なる場合は正常に動作しない場合もございますのでご了承下さい。

Visual C++5.0でのコンパイル

VC5.0でサンプルをコンパイルする場合は新規プロジェクト(Win32Application)を作成後、各ファイルを追加してビルドしてください。

Borland C++ Compiler 5.5でのコンパイル

BCC5.5でサンプルをコンパイルする場合は「bcc32.exe」で*.c又は*.cppファイルをコンパイルします。リソースがある場合は「brc32.exe」で*resファイルを付与してください。

サンプルについて

このWindows APIサンプル集(C/C++版)は2000年頃にC/C++言語の学習の為に作成したものです。コードはエレガントではなく「初心者レベルのコーディング」です。仕事などの業務で利用する際にはエラー処理やメモリ解放などの再確認を必ずして下さい。





関連記事



公開日:2015年03月19日
記事NO:00542