山本ワールド
Windowsプログラミング
アルゴリズム Vitual C++ 2008/2013によるWin32/Win64 APIレベルのプログラム 基礎 Vitual C++ 2008/2013によるAPIレベルのプログラム(32/64bit) Wix3でインストーラーを作る Visual C++ 2008 Standard Editonによるフォームアプリケーションのプログラム(32/64bit) Vitual C++ 2008 Standard EditonによるAPIレベルのプログラム(32/64bit) Windows 7対応 Visual C++ 2008 ExpressによるAPIレベルのプログラム Visual C++ 2005 ExpressによるAPIレベルのプログラム Visual C++ Versiosn 5 BORLAND C++ Windowsプログラム全般 Excel VBA その他ドラッグ&ドロップされた複数のWMAファイルの画像を変更するGUIプログラム(32/64bit)
概要
ドラッグ&ドロップされた複数のWMAファイルのアルバムアートの変更を行います。
テスト環境
コンパイラ
Visual C++ 2008/2013 Express 32/64bit UNICODE実行環境
Windows XP Professional Service Pack 3 32bit(Virtual Box上の仮想マシーン)Windows 7 Enterprise Service Pack 1 64bit
動作例
プログラムソースの概要
gwmaimg4.cpp
_tWinMain
ダイアログを表示します。DlgProc1
ダイアログボックスの初期化時にDlgProc1関数にWM_INITDIALOGメッセージが発生するので、ドラッグ&ドロップを許可します。ドラッグ&ドロップ
WMAファイルがドラッグ&ドロップされるとDlgProc1関数にWM_DROPFILESメッセージが発生するので、ファイル名を取得します。OKボタン
ボタンがクリックされると、DlgProc1関数にWM_COMMANDメッセージが発生するので、OKボタンのメッセージの場合、Jpegファイルを取得するコモンダイアログボックスを表示し、ファイル名が得られたならファイルサイズを調べます。ファイルサイズ分のメモリをGlobalAlloc APIで確保しハンドルを取得します。その後メモリをロックし先頭のアドレスを取得します。
メモリをストリームとして扱うため、CreateStreamOnHGlobal を実行しメモリストリームのハンドルを得ます。(ここでは画像を表示しないのでメモリーストリム化は不要ですが、コードの流用をしています。)
そのアドレスにJpegイメージを読み込みます。
WMAファイルのWM/Picture属性を検索し、属性が無ければAddAttribute、有ればModifyAttributeで画像を追加または変更します。
ソースコード
gwmaimg4.cpp
// ドラッグ&ドロップされたWMAファイルのアルバムアートを変更する
#include <windows.h>
#include <tchar.h>
#include <wmsdk.h>
#include <stdio.h>
#include "resource.h"
#pragma comment(lib,"wmvcore.lib")
// ファイル名を取得する
BOOL GetFileName(TCHAR* fname,int sz);
// ダイアログボックスのプロシージャー
LRESULT CALLBACK DlgProc1(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
// WMAファイルのアルバムアートを変更する
bool wma_jpg_chg(IWMMetadataEditor* pEditor,TCHAR* fname);
// メモリストリームを作成する
bool jpg_stream(IStream** pIStream,BYTE** jpg_mem,int sz,HGLOBAL* hBuf);
TCHAR* file=0;
BYTE* jpg_mem=0;
int sz;
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPreInst,TCHAR* lpszCmdLine, int nCmdShow){
TCHAR f[MAX_PATH];
if(lpszCmdLine[0]){
if(lpszCmdLine[0]==_T('\"')){
_tcscpy_s(f,sizeof(f)/sizeof(TCHAR),lpszCmdLine+1);
f[ _tcslen(f) -1]=_T('\0');
file=f;
}else
file=lpszCmdLine;
}
if(DialogBox(hInstance, TEXT("DLG1"), 0, (DLGPROC)DlgProc1)){
}
return 0;
}
// ダイアログボックスのプロシージャー
LRESULT CALLBACK DlgProc1(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam){
IWMMetadataEditor* pEditor=NULL;
HRESULT hr;
TCHAR buf[MAX_PATH];
HDROP hDrop;
UINT fmax;
FILE* fp;
static HGLOBAL hBuf=0;
static IStream* pIStream=0;
int i;
static bool edit=false;
switch (msg) {
case WM_INITDIALOG:
DragAcceptFiles(hDlg, TRUE);
if (file)
SendMessage(GetDlgItem(hDlg, IDC_LISTBOX1), LB_ADDSTRING, 0, (LPARAM)file);
return TRUE;
case WM_DROPFILES:
hDrop = (HDROP)wParam;
fmax = DragQueryFile((HDROP)wParam, 0xFFFFFFFF, NULL, 0);
for (i = 0; i < (int)fmax; i++) {
DragQueryFile(hDrop, i, buf, sizeof(buf) / sizeof(TCHAR));
SendMessage(GetDlgItem(hDlg, IDC_LISTBOX1), LB_ADDSTRING, 0, (LPARAM)buf);
}
DragFinish(hDrop);
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
fmax = (UINT)SendMessage(GetDlgItem(hDlg, IDC_LISTBOX1), LB_GETCOUNT, 0, 0);
if(0<fmax){
if(GetFileName(buf,sizeof(buf)/sizeof(TCHAR))){
if(_tfopen_s(&fp,buf,_TEXT("rb"))==0){
fseek(fp,0,SEEK_END);
sz=ftell(fp);
fseek(fp,0,SEEK_SET);
if(jpg_stream(&pIStream,&jpg_mem,sz,&hBuf)==false){
MessageBox(hDlg,_TEXT("メモリ確保に失敗しました。"),_TEXT("エラー"),MB_OK);
fclose(fp);
GlobalFree(hBuf);
EndDialog(hDlg, TRUE);
}
fread(jpg_mem,sizeof(BYTE),sz,fp);
fclose(fp);
hr = WMCreateEditor(&pEditor); // オブジェクトを作成
for (i = 0; i < (int)fmax; i++){
SendMessage(GetDlgItem(hDlg, IDC_LISTBOX1), LB_GETTEXT, i, (LPARAM)buf);
wma_jpg_chg(pEditor, buf);
}
MessageBox(hDlg, _TEXT("変換しました"), _TEXT("メッセージ"), MB_OK);
}
}else{
MessageBox(hDlg, _TEXT("Jpegファイルが開けません"), _TEXT("エラー"), MB_OK);
}
}
EndDialog(hDlg, TRUE);
return TRUE;
case IDCANCEL:
EndDialog(hDlg,FALSE);
default:
return FALSE;
}
default:
return FALSE;
}
return TRUE;
}
// ファイル名を取得する
BOOL GetFileName(TCHAR* fname,int sz){
OPENFILENAME o;
fname[0]=_T('\0');
ZeroMemory(&o,sizeof(o));
o.lStructSize=sizeof(o);
o.Flags=0;
o.lpstrFile=fname;
o.nMaxFile=sz;
o.lpstrFilter=_TEXT("wma\0");
o.nFilterIndex=1;
return GetOpenFileName(&o);
}
TCHAR* errstr(HRESULT v){
switch(v){
case S_OK: return _TEXT("成功");
case E_INVALIDARG: return _TEXT("違法なパラメータの組合せ、データ型または属性が、使われました。");
case E_NOTIMPL: return _TEXT("実装されません。");
case E_POINTER: return _TEXT("ポインターは、有効でありません");
case NS_E_ATTRIBUTE_READ_ONLY: return _TEXT("属性は変わることができません。");
case NS_E_INVALID_REQUEST: return _TEXT("wStreamNumは有効な番号でありません、または、属性がwIndexにありません");
default: return _TEXT("不明なエラーです。");
}
}
// WMAファイルのアルバムアートを変更する
bool wma_jpg_chg(IWMMetadataEditor* pEditor,TCHAR* fname){
bool flag=false;
HRESULT hr;
IWMHeaderInfo3* pHeaderInfo=NULL;
hr=pEditor->Open(fname);
pEditor->QueryInterface(IID_IWMHeaderInfo3,(void**)&pHeaderInfo);
WORD wStreamNum = 0;
WMT_ATTR_DATATYPE Type;
WORD cbLength=0;
TCHAR* getname;
TCHAR pwszTitle[1024];
WM_PICTURE pP;
int index=-1;
WORD cAttr=0;
DWORD cbValue=0;
hr = pHeaderInfo->GetAttributeCountEx(0xffff,&cAttr);
for(int i=0;i<cAttr;i++){
cbLength=sizeof(pwszTitle)/sizeof(TCHAR);
hr=pHeaderInfo->GetAttributeByIndexEx(wStreamNum,i,pwszTitle,&cbLength,&Type,NULL,NULL,&cbValue);
if(_tcscmp(pwszTitle,g_wszWMPicture)==0){
index=i;
break;
}
}
Type=WMT_TYPE_BINARY;
getname=(TCHAR*)g_wszWMPicture;
pP.bPictureType=3;
pP.dwDataLen=sz;
pP.pbData=jpg_mem;
pP.pwszDescription=_TEXT("");
pP.pwszMIMEType=_TEXT("image/jpeg");
cbLength = (WORD)(sz+(_tcslen(pP.pwszDescription)+_tcslen(pP.pwszMIMEType)+2)*sizeof(TCHAR)+sizeof(pP));
WORD d=0;
if(index<0)
hr=pHeaderInfo->AddAttribute(wStreamNum, getname,&d,Type,0,(BYTE*)&pP,cbLength);
else
hr=pHeaderInfo->ModifyAttribute(wStreamNum, index, Type,0,(BYTE*)&pP,cbLength);
if(hr!=S_OK){
MessageBox(0,errstr(hr),_TEXT("Set/Modify Attribute API Error"),MB_OK);
}
pHeaderInfo->Release();
pEditor->Flush();
return flag;
}
// メモリストリームを作成する
bool jpg_stream(IStream** pIStream,BYTE** jpg_mem,int sz,HGLOBAL* hBuf){
*hBuf=GlobalAlloc(GMEM_MOVEABLE,sz);
if(*hBuf==0){
MessageBox(0,_TEXT("GlobalAlloc APIでのメモリの確保に失敗しました"),_TEXT("エラー"),MB_OK);
return false;
}
*jpg_mem=(BYTE*)GlobalLock(*hBuf);
if(*jpg_mem==0){
MessageBox(0,_TEXT("GlobalLock APIでのメモリのロックに失敗しました"),_TEXT("エラー"),MB_OK);
GlobalFree(*hBuf);
return false;
}
*pIStream=0;
if(CreateStreamOnHGlobal(*hBuf,FALSE,pIStream)!=S_OK){
MessageBox(0,_TEXT("CreateStreamOnHGlobal APIでのメモリストリームの作成に失敗しました"),_TEXT("エラー"),MB_OK);
GlobalFree(*hBuf);
return false;
}
return true;
}
resource.h
#define IDC_LISTBOX1 2001
resource.rc
#include <windows.h>
#include "resource.h"
DLG1 DIALOG DISCARDABLE 0, 0, 320, 221
STYLE DS_MODALFRAME | WS_POPUP
CAPTION "WMAファイルアルバムアートの変更"
FONT 9, "MS Pゴシック"
BEGIN
LTEXT "ここへファイルをドラッグドロップしてください", -1, 7, 7, 168, 10
CONTROL "ListBox", IDC_LISTBOX1, "LISTBOX", WS_CHILD | WS_VISIBLE | WS_VSCROLL | LBS_DISABLENOSCROLL, 7, 21, 306, 163
DEFPUSHBUTTON "OK(&O)",IDOK,100,197,50,14
PUSHBUTTON "キャンセル(&C)",IDCANCEL,157,197,50,14
END
Copyright (C) 2012 山本ワールド All Rights Reserved.