今回は(コントロールはないので)メニュー関連関数を解説します。いつも通り、解説は(解説:)で入れましょう。
/////////////////////////////////
//主ウィンドウICONVIEWERの関数の定義
//メニュー項目、コントロール関数
/////////////////////////////////
bool ICONVIEWER::OnOpen() {
if(g_ByFile)
g_ByFile = FALSE; //(解説:デフォルトのFALSE状態に戻し、g_FileNameに入れておいたファイルを読みに行く、ということです。)
else {
char* cp = cmndlg.GetFileName(m_hWnd, "アイコンファイル(*.ico)\0*.ico\0カーソルファイル(*.cur)\0*.cur\0\0", TRUE);
if(cp)
g_FileName = cp; //cpがNULLでなければファイル名をg_FileNameへコピー
else {
MessageBox(m_hWnd, "操作はキャンセルされました", "メッセージ", MB_OK | MB_ICONERROR);
return FALSE;
} //(解説:コモンダイアログクラスのファイルを開くダイアログを利用しています。戻り値のファイルパス・名がなければエラーとなります。)
}
//ファイル読込処理
if(strstr(g_FileName.ToChar(), ".ico") || strstr(g_FileName.ToChar(), ".ICO")) { //Iconファイル
g_ImageType = IMAGE_ICON;
if(!g_Icon.Load_Icon(g_FileName.ToChar(), IMAGE_ICON, TRUE)) {
MessageBox(m_hWnd, "アイコンファイルを読み込めませんでした", "エラー", MB_OK | MB_ICONSTOP);
return FALSE;
}
}
else if(strstr(g_FileName.ToChar(), ".cur") || strstr(g_FileName.ToChar(), ".CUR")) { //Cursorファイル
g_ImageType = IMAGE_CURSOR;
if(!g_Icon.Load_Icon(g_FileName.ToChar(), IMAGE_CURSOR, TRUE)) {
MessageBox(m_hWnd, "カーソルファイルを読み込めませんでした", "エラー", MB_OK | MB_ICONSTOP);
return FALSE;
}
}
//(解説:ファイル名拡張子をチェックしてiconかcursorか判断し、MicroSoftの定義するイメージファイル区分をグローバル変数に代入します。今思えば最初のif節はg_FileTypeだけにして、並列したif節でLoad_Icon関数を使ってもよかったですね。サイズの無駄でした。)
//アイコンを表示
SendItemMsg(IDC_ICONVIEW, STM_SETIMAGE, IMAGE_ICON, (LPARAM)g_Icon.GetIcon()); //(解説:SendDlgItemMessageのBCCSkelton版です。)
//リストビューに登録ビットマップ情報を表示
SetListView(); //(解説:ユーザー定義関数です。次回やります。)
//ファイル名をステータスバーに表示
SBar.SetText(1, g_FileName.ToChar());
SBar.SendMsg(SB_SETTIPTEXT, 1, (LPARAM)g_FileName.ToChar()); //ToolTipをつける
//(解説:ステータスバーの処理はワンパターンです。)
return TRUE;
}
bool ICONVIEWER::OnSave() {
if(!*g_FileName.ToChar()) //(解説:ファイル名を入れておくグローバル変数がNULLならOnSaveas()関数へ転送します。)
OnSaveas();
else
g_Icon.Save_Icon(g_FileName.ToChar(), g_ImageType); //(解説:Save_Icon()関数ですが、g_ImageType引数でcursorも識別します。)
return TRUE;
}
bool ICONVIEWER::OnSaveas() {
char *flt, *ext; //(解説:flt文字列ポインターはファイルを開くダイアログのフィルター用、extは拡張子用です。)
//IDD_SAVEダイアログの表示
savedlg.DoModal(m_hWnd, "IDD_SAVE", savedlgProc); //(解説:これがBCCSkeltonのモーダルダイアログ呼び出しです。IDD_SAVEでg_ImageTyeが選択されます。)
if(g_ImageType == IMAGE_ICON) {
flt = "アイコンファイル(*.ico)\0*.ico\0\0";
ext = "ico";
}
else {
flt = "カーソルファイル(*.cur)\0*.cur\0\0";
ext = "cur";
int num = g_Icon.GetCount();
for(int i = 0; i < num; i++) {
//ビットマップを表示
SendItemMsg(IDC_BMPVIEW, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)g_Icon.GetColBmp(i));
SendItemMsg(IDC_MSKVIEW, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)g_Icon.GetMaskBmp(i));
//ホットスポットの設定
g_Num = i;
hotspotdlg.DoModal(m_hWnd, "IDD_HOTSPOT", hotspotdlgProc);
} //(解説:イメージ区分でフィルターと拡張子を設定するのと、カーソルの場合、すべてのビットマップでIDD_HOTSPOTダイアログを呼び出してhotspotを入力させます。)
}
char* cp = cmndlg.GetFileName(m_hWnd, flt, FALSE, ext);
if(cp)
g_FileName = cp; //cpがNULLでなければファイル名をg_FileNameへコピー
else {
MessageBox(m_hWnd, "操作はキャンセルされました", "メッセージ", MB_OK | MB_ICONERROR);
return FALSE;
}
g_Icon.Save_Icon(g_FileName.ToChar(), g_ImageType); //(解説:ここで保存します。)
//ファイル名をステータスバーに表示
SBar.SetText(1, g_FileName.ToChar());
SBar.SendMsg(SB_SETTIPTEXT, 1, (LPARAM)g_FileName.ToChar()); //ToolTipをつける
return TRUE;
}
bool ICONVIEWER::OnBmpsave() {
int n = ListView_GetNextItem(GetDlgItem(m_hWnd, IDC_LISTVIEW), -1,
LVNI_ALL | LVIS_SELECTED); //(解説:リストビューの選択状況をチェック。)
if(n == -1) { //未選択なら何もしない
MessageBox(m_hWnd, "ビットマップが選択されていません", "エラー", MB_OK | MB_ICONERROR);
return FALSE;
}
else { //選択されている場合
char* flt = "ビットマップファイル(*.bmp)\0*.bmp\0\0";
char* ext = "bmp";
char* cp = cmndlg.GetFileName(m_hWnd, flt, FALSE, ext);
if(!cp) {
MessageBox(m_hWnd, "キャンセルされました", "エラー", MB_OK | MB_ICONERROR);
return FALSE;
} //(解説:フィルター、拡張子、コモンダイアログクラスの使い方はもうやりました。)
CBMP bmp(g_Icon.GetColBmp(n));
bmp.SaveBMP(cp);
//(解説:ローカル変数としてCBMPクラスのインスタンスbmpをCICONクラスインスタンスのg_Iconのn番目のカラービットマップのハンドルを取得するGetColBmp(n)を与えて作成し、ビットマップを保存します。とても簡単ですね。)
}
return TRUE;
}
bool ICONVIEWER::OnExit() {
SendMsg(WM_CLOSE, 0, 0); //(解説:OnExit()関数の定番です。)
return TRUE;
}
bool ICONVIEWER::OnAdd() {
char* flt = "ビットマップファイル(*.bmp)\0*.bmp\0\0";
char* cp = cmndlg.GetFileName(m_hWnd, flt, TRUE);
if(!cp) {
MessageBox(m_hWnd, "キャンセルされました", "エラー", MB_OK | MB_ICONERROR);
return FALSE;
} //(解説:コモンダイアログクラスの定番処理です。)
int n = g_Icon.GetCount(); //個数は次のビットマップカウンターと同じ
if(!g_Icon.Add_Bitmap(cp)) //ビットマップを追加する
return FALSE; //(解説:g_Icon.Add_BitmapがFALSEを返した場合、!でTRUEにしてここで退場です。)
//ビットマップを表示 (解説:ダイアログにカラービットマップ、マスクビットマップを表示します。)
SendItemMsg(IDC_BMPVIEW, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)g_Icon.GetColBmp(n));
SendItemMsg(IDC_MSKVIEW, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)g_Icon.GetMaskBmp(n));
//エディットボックスの表示
ShowIconData(n); //(解説:これもユーザー定義関数で、次回やります。)
//リストビューに登録ビットマップ情報を表示
SetListView();
return TRUE;
}
bool ICONVIEWER::OnDelete() {
int n = ListView_GetNextItem(GetDlgItem(m_hWnd, IDC_LISTVIEW), -1,
LVNI_ALL | LVIS_SELECTED); //(解説:リストビューの選択確認です。)
if(n == -1) {
MessageBox(m_hWnd, "ビットマップが選択されていません", "エラー", MB_OK | MB_ICONERROR);
return FALSE;
}
g_Icon.Del_Bitmap(n); //(解説:アイコンの構成ビットマップのn番目を削除します。)
//表示消去用のビットマップ (解説:削除したのだから表示し続けると格好悪いですよね?で無地ビットマップを作って消します。)
HDC hDC = GetDC(m_hWnd);
HBITMAP hNull = CreateCompatibleBitmap(hDC, 32, 32);
ReleaseDC(m_hWnd, hDC);
//消去用ビットマップを表示
SendItemMsg(IDC_BMPVIEW, STM_SETIMAGE, 0, (LPARAM)hNull);
SendItemMsg(IDC_MSKVIEW, STM_SETIMAGE, 0, (LPARAM)hNull);
DeleteObject(hNull);
//エディットボックスの表示
SendItemMsg(IDC_EDIT, WM_SETTEXT, 0, (LPARAM)0); //(解説:削除したビットマップの詳細データも消去します。)
//リストビューに登録ビットマップ情報を表示
SetListView(); //(解説:削除-前詰めした後no-リストビューを表示します。)
return TRUE;
}
bool ICONVIEWER::OnDisplay() {
int n = ListView_GetNextItem(GetDlgItem(m_hWnd, IDC_LISTVIEW), -1,
LVNI_ALL | LVIS_SELECTED);
if(n== -1) {
MessageBox(m_hWnd, "ビットマップが選択されていません", "エラー", MB_OK | MB_ICONERROR);
return FALSE;
}
//ビットマップを表示
SendItemMsg(IDC_BMPVIEW, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)g_Icon.GetColBmp(n));
SendItemMsg(IDC_MSKVIEW, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)g_Icon.GetMaskBmp(n));
//エディットボックスの表示
ShowIconData(n);
return TRUE;
} //(解説:リストビューを選択したときの動作を行うだけです。-実は元々の仕様がダブルクリックで表示させていたのでその名残です。汗;)
bool ICONVIEWER::OnHelp() {
//(解説:文字列を扱うCSTRクラスの使い方としてみてください。)
CSTR cmd = "hh \""; //(解説:MicrosoftのHTMLヘルプ(hh.exe)を使います。パスが通っているのでこれで大丈夫です。スペースの後の'\"'は、ファイルパスにスペースがあることが考えられるので、二重コンマを作るためです。)
cmd = cmd + g_HelpFile + "\""; //(解説:上の文字列にOnInit()関数で設定したヘルプファイルパス・名を追加します。この結果、cmdは"hh \"ヘルプファイルのパス・名.chm\""→「hh "ヘルプファイルのパス・名.chm"」状態を、次のWinExec()関数でcommand.comに与えます。)
WinExec(cmd.ToChar(), SW_SHOWNORMAL);
return TRUE;
}
bool ICONVIEWER::OnVersion() {
//IDD_VERSIONダイアログの表示
versiondlg.DoModal(m_hWnd, "IDD_VERSION", versiondlgProc); //(解説:バージョンダイアログを呼び出します。)
return TRUE;
}
今回はここまでです。