第104章 ファイルを開く


今回は、表題の通り「ファイルを開く」プログラムを作ります。 Windowsでは、ファイルのアイコンをダブルクリック(またはクリック) すると、そのファイルに関連づけられたアプリケーションが起動して そのファイルを開きます。たとえば*.txtファイルが「メモ帳」に 関連づけられていればメモ帳を起動してそのファイルを開きます。



メニューの「ファイル」「開く」からファイルを選択すると そのファイルに関連づけられたアプリケーションが起動してファイルを 開きます。また、実行ファイルを選択するとそれが起動します。 「オプション」「印刷」を選択しておくと(チェックマークがつく) 関連づけられたアプリケーションを通して印刷することもできます。 今回は簡単なので、おまけでアイコンも作ってみました。



VC++の人は「アイコンの新規作成」ボタンを押して、左のようなアイコンを作ります。 名前は"MYICON"にしておきます。

// shex01.rcの一部 ///////////////////////////////////////////////////////////////////////////// // // Menu // MYMENU MENU DISCARDABLE BEGIN POPUP "ファイル(&F)" BEGIN MENUITEM "開く(&O)", IDM_OPEN MENUITEM "終了(&X)", IDM_END END POPUP "オプション(&O)" BEGIN MENUITEM "印刷(&P)", IDM_PRINT END END ///////////////////////////////////////////////////////////////////////////// // // Icon // MYICON ICON DISCARDABLE "myicon.ico"

単なるメニューとアイコンのリソーススクリプトです。

// shex01.cpp #define STRICT #include <windows.h> #include "resource.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); BOOL InitApp(HINSTANCE); BOOL InitInstance(HINSTANCE, int); void OpenF(HWND, BOOL); char szClassName[] = "shex01"; //ウィンドウクラス int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow) { MSG msg; if (!InitApp(hCurInst)) return FALSE; if (!InitInstance(hCurInst, nCmdShow)) return FALSE; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }

いつもと同じです。

//ウィンドウ・クラスの登録 BOOL InitApp(HINSTANCE hInst) { 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 = LoadIcon(hInst, "MYICON"); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszMenuName = "MYMENU"; //メニュー名 wc.lpszClassName = (LPCSTR)szClassName; wc.hIconSm = LoadIcon(hInst, "MYICON"); return (RegisterClassEx(&wc)); }

自作アイコンを作ったのでhIconとhIconSmメンバを指定してください。 第29章も参照してください。 なお、hIconはアプリケーションのショートカットなどを作ったときなどに 使われる大きいアイコン、hIconSmはタイトルバーの左端にあるような 小さいアイコンを指定します。今回はどちらも同じものを使いました。

//ウィンドウの生成 BOOL InitInstance(HINSTANCE hInst, int nCmdShow) { HWND hWnd; hWnd = CreateWindow(szClassName, "猫でも開けるプログラム!", //タイトルバーにこの名前が表示されます WS_OVERLAPPEDWINDOW, //ウィンドウの種類 CW_USEDEFAULT, //X座標 CW_USEDEFAULT, //Y座標 270, //幅 160, //高さ NULL, //親ウィンドウのハンドル、親を作るときはNULL 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) { int id; static HMENU hMenu; static BOOL bPrint; switch (msg) { case WM_CREATE: hMenu = GetMenu(hWnd); CheckMenuItem(hMenu, IDM_PRINT, MF_BYCOMMAND | MF_UNCHECKED); bPrint = FALSE; break; case WM_COMMAND: switch (LOWORD(wp)) { case IDM_END: SendMessage(hWnd, WM_CLOSE, 0, 0); break; case IDM_OPEN: OpenF(hWnd, bPrint); break; case IDM_PRINT: if (bPrint) { CheckMenuItem(hMenu, IDM_PRINT, MF_BYCOMMAND | MF_UNCHECKED); bPrint = FALSE; } else { CheckMenuItem(hMenu, IDM_PRINT, MF_BYCOMMAND | MF_CHECKED); bPrint = TRUE; } break; } break; case WM_CLOSE: id = MessageBox(hWnd, (LPCSTR)"終了してもよいですか", (LPCSTR)"終了確認", MB_YESNO | MB_ICONQUESTION); if (id == IDYES) { DestroyWindow(hWnd); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return (DefWindowProc(hWnd, msg, wp, lp)); } return 0L; }

WM_CREATEの時、印刷オプションはオフにしておきます。 この例ではわざわざCheckMenuItem関数で「印刷」項目に チェックを付けない指定をしていますが、この関数を 実行しなくても最初からチェックは付いていないので 削除してもかまいません。

メニューから「開く」(IDM_OPEN)が選択されたら、 自作関数OpenF()を呼びます。

メニューから「印刷」(IDM_PRINT)が選択されたら、 メニューチェックの状態を変化させます。 (チェックが付いてたらはずし、ついていなかったら付ける) そして、bPrint変数の値をそれに見合ったものにします。

void OpenF(HWND hWnd, BOOL bPrint) { OPENFILENAME ofn; char szFileName[64]; char szFile[MAX_PATH]; memset(&ofn, 0, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hWnd; ofn.lpstrFilter = "text(*.txt)\0*.txt\0All files(*.*)\0*.*\0\0"; ofn.lpstrFile = szFileName; ofn.lpstrFileTitle = szFile; ofn.nMaxFile = MAX_PATH; ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; ofn.lpstrDefExt = "txt"; ofn.lpstrTitle = "実行したいファイルを選択"; if(GetOpenFileName(&ofn) == 0) return; if (!bPrint) { if(ShellExecute(hWnd, NULL, szFile, NULL, NULL, SW_SHOWNORMAL) <= (HINSTANCE)32) MessageBox(hWnd, "実行に失敗しました", "失敗", MB_OK); } if (bPrint) { if(ShellExecute(hWnd, "print", szFile, NULL, NULL, SW_SHOWNORMAL) <= (HINSTANCE)32) MessageBox(hWnd, "印刷に失敗しました", "失敗", MB_OK); } return; }

自作関数です。何をやっているかというとコモンダイアログの「ファイルを開く」ダイアログを 呼んで、得られたファイル名からShellExecute関数を呼んでいるだけです。
「ファイルを開く」ダイアログは 第73章を参照してください。

HINSTANCE ShellExecute( HWND hwnd, // 親ウィンドウのハンドル LPCTSTR lpOperation,// 「操作」を表す文字列へのポインタ LPCTSTR lpFile, // ファイル名またはディレクトリ名へのポインタ LPCTSTR lpParameters,// 実行可能ファイルの文字列のアドレス LPCTSTR lpDirectory, // デフォルトのディレクトリ INT nShowCmd // 実行するときのファイルの表示の有無 );

lpOperationには"open", "print", "explore"のいずれかを指定します。 NULLを指定するとデフォルトとして"open"になります。

lpFileには、オープンするファイルを指定します。

lpParametersには、lpFileが実行可能ファイルのときこれに渡す パラメータを指定します。文書ファイルならNULLになります。

lpDirectoryにはデフォルトのディレクトリを指定します。

nShowCmdにはアプリケーションをオープンするときウィンドウを 表示するかどうかを指定します。ShowWindow関数の第2引数と同じです。

戻り値は表示するアプリケーションのインスタンスハンドルとなります。 これが32以下の時はエラーです。


[SDK第2部 Index] [総合Index] [Previous Chapter] [Next Chapter]

Update Jan/31/1998 By Y.Kumei
当ホーム・ページの一部または全部を無断で複写、複製、 転載あるいはコンピュータ等のファイルに保存することを禁じます。