2012年3月31日土曜日
2012年3月27日火曜日
CreateDialog + サブクラス化 + RegisterClassEx
ウィンドウプロシージャでthisポを使いたいってんでサブクラス化するんだけど、CreateDialogでウィンドウを作成する場合はどうすりゃいいんじゃろ? と試行錯誤してた。
結局下のようになった。CreateWindow()みたいにlparamにデータを渡せればスマートなんだけど仕方なし。あとCreateDialog()なのにウィンドウプロシージャを使用するあたりやや気持ち悪いが。
[resource.h]
[resource.rc]
[main.cpp]
迷う点は二つで、WNDCLASSEX のlpfnWndProcと、CreateDialog()の第4引数 lpDialogFunc。
CreateDialogParam()を使用すればLPARAMに好きなデータを渡せるから、INIT_DIALOGでGWL_USERDATAにthisポを保存する計画だった。
でもWNDCLASSEXに指定するプロシージャはLRESULT CALLBACK wndProc()、いわゆるウィンドウプロシージャで、CreateDialogに指定するのはBOOL CALLBACK wndProc()ってダイアログプロシージャと型が違うのね。
両方設定すべく、reinterpret_castで無理やり型変更して指定するもウィンドウが生成されない問題が出た。
どちらかのプロシージャ設定でNULLを指定しなければならないようだけど、いろいろ試したが、WNDCLASSEXのプロシージャ設定をNULLにしちゃうとうまく処理できないようだった。というのもダイアログプロシージャのほうはDefWindowProc()とかで汎用処理を行わないから全うに動くはずもない。
結局下のようになった。CreateWindow()みたいにlparamにデータを渡せればスマートなんだけど仕方なし。あとCreateDialog()なのにウィンドウプロシージャを使用するあたりやや気持ち悪いが。
[resource.h]
#pragma once
#define APP_CLASS_NAME TEXT("test")
#define APP_TITLE TEXT("test")
#define IDD_MAIN 101
[resource.rc]
#include "resource.h"
#include <windows.h>
IDD_MAIN DIALOG 0, 0, 310, 210
FONT 9, "MS Pゴシック"
STYLE WS_VISIBLE | WS_POPUPWINDOW
CAPTION APP_TITLE
{}
[main.cpp]
#include <windows.h>
#include "resource.h"
class WindowBase
{
protected:
/** constructor */
WindowBase() {}
/** destructor */
virtual ~WindowBase() {}
static void attachWnd( HWND hWnd, LONG_PTR myWndData )
{
SetWindowLongPtr( hWnd, GWL_USERDATA, myWndData );
SetWindowLongPtr( hWnd, GWL_WNDPROC, reinterpret_cast<LONG_PTR>(staticWndProc) );
}
public:
/** 初期化プロシージャ */
static LRESULT CALLBACK initWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
if ( uMsg == WM_CREATE )
{
LPCREATESTRUCT cs = reinterpret_cast<LPCREATESTRUCT>( lParam );
WindowBase* wb = static_cast<WindowBase*>( cs->lpCreateParams );
attachWnd( hWnd, reinterpret_cast<LONG_PTR>(wb) );
return wb->wndProc( hWnd, uMsg, wParam, lParam );
}
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
/** 間接参照プロシージャ */
static LRESULT CALLBACK staticWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
return reinterpret_cast<WindowBase*>( GetWindowLongPtr(hWnd, GWL_USERDATA) )->wndProc( hWnd, uMsg, wParam, lParam );
}
/** オーバーライドして使用するプロシージャ */
virtual LRESULT wndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
// サブクラス化でない場合は、デフォルトウィンドウプロシージャを呼び出す
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
};
/**
* Main
*/
class Main : public WindowBase
{
public:
/**
* constructor
*/
Main()
: m_hWnd( NULL )
{}
/**
* destructor
*/
~Main() {}
/**
* override wndProc
*/
LRESULT wndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
switch ( uMsg )
{
case WM_CREATE:
break;
case WM_CLOSE:
DestroyWindow( hWnd );
break;
case WM_DESTROY:
ShowWindow( hWnd, SW_HIDE );
PostQuitMessage(0);
break;
}
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
static LRESULT CALLBACK dummyProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
return DefWindowProc( hWnd, uMsg, wParam, lParam );
}
/**
* WinMain
*/
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
// register
{
WNDCLASSEX wc = {0};
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = dummyProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = DLGWINDOWEXTRA;
wc.cbSize = sizeof( WNDCLASSEX );
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hIconSm = NULL;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground= reinterpret_cast<HBRUSH>( GetStockObject( WHITE_BRUSH ) );
wc.lpszMenuName = NULL;
wc.lpszClassName= APP_CLASS_NAME;
if ( !RegisterClassEx( &wc ) ) return 0;
}
m_hWnd = CreateDialog( hInstance, reinterpret_cast<LPCTSTR>(IDD_MAIN), NULL, NULL );
if ( !m_hWnd ) return -1;
attachWnd( m_hWnd, reinterpret_cast<LONG_PTR>(this) );
ShowWindow( m_hWnd, SW_SHOWNORMAL );
SendMessage( m_hWnd, WM_CREATE, 0, 0 );
// message loop
{
MSG msg;
while ( GetMessage(&msg , NULL , 0 , 0) )
{
if ( !IsDialogMessage(m_hWnd, &msg) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
}
return 0;
}
private:
HWND m_hWnd;
};
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpsCmdLine, int nCmdShow)
{
Main mainWindow;
return mainWindow.WinMain( hInst, hPrevInst, lpsCmdLine, nCmdShow );
}
迷う点は二つで、WNDCLASSEX のlpfnWndProcと、CreateDialog()の第4引数 lpDialogFunc。
CreateDialogParam()を使用すればLPARAMに好きなデータを渡せるから、INIT_DIALOGでGWL_USERDATAにthisポを保存する計画だった。
でもWNDCLASSEXに指定するプロシージャはLRESULT CALLBACK wndProc()、いわゆるウィンドウプロシージャで、CreateDialogに指定するのはBOOL CALLBACK wndProc()ってダイアログプロシージャと型が違うのね。
両方設定すべく、reinterpret_cast
どちらかのプロシージャ設定でNULLを指定しなければならないようだけど、いろいろ試したが、WNDCLASSEXのプロシージャ設定をNULLにしちゃうとうまく処理できないようだった。というのもダイアログプロシージャのほうはDefWindowProc()とかで汎用処理を行わないから全うに動くはずもない。
2012年3月25日日曜日
ZenStyleM100-CreatePlayList v101
https://skydrive.live.com/redir.aspx?cid=8cd7cf5ea9fbca55&resid=8CD7CF5EA9FBCA55!387&parid=8CD7CF5EA9FBCA55!138&authkey=!ABffr6vVY5sxtMM
size: 7KB
■概要
ZenStyleM100にてフォルダ別にプレイリストを作成する
■使い方
お使いのZenStyleM100のルートフォルダにCreatePlayList101.vbsを置いて実行してください。
ファイル内の outputDirectory および searchDirectory のパスを書き換えれば
お好きな位置で実行することもできます。
Musicフォルダ直下にあるフォルダ名で、PlayListフォルダにプレイリストが出力されます。
(デフォルトの場合)
■使い方(詳しく)
1. お使いのM100のルートフォルダにダウンロードしたCreatePlayList.vbsを置いてください。
2. CreatePlayList.vbsを実行
(windowsならダブルクリックで実行される。ほかは知らん)
確認ウィンドウがでるので良ければ[OK]
3. しばし終わるのを待つ
終わったら[終了]と出ます
その後本体起動時にリストのチェックが入るのか起動時間が長くなります。
気長にお待ちくださいませ。
無事プレイリストの読み込みが完了した
Musicフォルダには以下画像のように配置しています。
完了後のPlayListフォルダはこんな感じに。
■仕様
設定したフォルダパス(デフォではMusic)内にあるフォルダの数だけm3uを作成します。
たとえば、
G:.
├─Music
│ ├─フォルダ1
│ │ ├─01.mp3
│ │ └─02.mp3
│ ├─フォルダ2
│ │ ├─disc1
│ │ │ ├─01.mp3
│ │ │ ├─02.mp3
│ │ │ └─03.mp3
│ │ └─disc2
│ │ ├─01.mp3
│ │ ├─02.mp3
│ │ └─03.mp3
│ └─フォルダ3
├─Pictures
├─Video
├─Recorded
└─Playlist
って構成になっていたら作成されるm3uは
フォルダ1.m3u
フォルダ2.m3u
の2つが、PlayListフォルダに出力されます。
フォルダ2は中にさらにフォルダがありますが、
まとめてフォルダ2.m3uに保存されることになります。
またフォルダ3には曲がないのでフォルダ3.m3uは出力されません。
CreatePlayList.vbsの中身を書き換えることで、
出力先フォルダ、入力フォルダを変更することができます。
デフォルトではPlayListフォルダに出力する設定になっていますが、
既存のプレイリストとごちゃごちゃになるのが気になる方は出力先を変更すると良いでしょう。
' Zen Style M100の曲ファイルをフォルダ別にm3uにして、PlayListに保存するプログラム ' 2012-03-25 ver 1.01 ' author sumishiro@gmail.com ' 本プログラムのご利用に際し如何なる損失や損害が発生しても、一切の責任を負いかねます。ご了承ください。 ' ' 1012-03-25 ver 1.01 ' フォルダとファイルのタイムスタンプ(作成日時、更新日時)、m3u内のファイルの有無、ファイル数をチェックする機能を追加 ' 1012-03-21 ver 1.00 Option Explicit Dim outputDirectory Dim searchDirectory Dim rootFileName ' m3u出力先。フォルダが存在しないと出力されないようなので注意 outputDirectory = ".\PlayList" ' 調べるディレクトリパス ' このディレクトリにあるフォルダ名でm3uファイルを作成し、 ' 各フォルダ内にある音楽ファイルをm3uに突っ込む ' 同名のm3uは上書きされるので注意 searchDirectory = ".\Music" ' searchDirectoryに直接おいてある曲もm3uリストにしたい場合 ' 以下に出力m3uファイル名を定義してね ' rootFileName = "root" Dim fso Set fso = WScript.CreateObject("Scripting.FileSystemObject") ' 指定m3uファイルをチェック。 ' ファイルがすべて存在してm3uとして問題がなければTrueを返す。 ' 参照引数rLineNumに該当ファイルの行数(記述されたファイル数)を入れるが、 ' 存在しないファイルがあった場合は最後までカウントしないので注意 Function checkPlayList( fileObj, rLineNum ) Dim file Set file = fso.OpenTextFile( fileObj, 1, False, -1 ) ' C: D:といったドライブ名を取得 Dim driveName driveName = Left( searchDirectory, InStr(searchDirectory, "\") ) rLineNum = 0 Do Until file.AtEndOfStream=True Dim strLine strLine = file.ReadLine() If fso.FileExists(driveName & strLine)=False Then checkPlayList = False Exit Function End If rLineNum = rLineNum + 1 Loop file.Close() checkPlayList = True End Function ' m3uの作成が必要かどうかチェック。 ' 指定した日時よりファイル日時のほうが新しければFalse, それ以外はTrue ' @return 作成の必要があるならばTrue Function needCreatePlayListFile( filePath, dateTime, musicFileNum ) If fso.FileExists(filePath) Then ' m3uが指定時刻より新しいかチェック。新しければ関数終了 If fso.GetFile(filePath).DateLastModified < dateTime Then needCreatePlayListFile = True Exit Function End If ' m3uファイルの妥当性チェック Dim lineNum If checkPlayList(fso.GetFile(filePath), lineNum) Then ' 数チェック If lineNum=musicFileNum Then needCreatePlayListFile = False Exit Function End If End If End If needCreatePlayListFile = True End Function ' 引数date, file.更新日時, file.作成日時の3つの中から一番最新の日時を返す ' fileにはFileオブジェクトかFolderオブジェクト Function getMostNewDate( file, date ) Dim tmp tmp = date If file.DateLastModified > tmp Then tmp = file.DateLastModified End If If file.DateCreated > tmp Then tmp = file.DateCreated End If getMostNewDate = tmp End Function ' 指定ファイル名とoutputDirectoryからm3uファイルのパスを作成 Function createM3UFilePath( fileName ) createM3UFilePath = fso.BuildPath( outputDirectory, fileName & ".m3u" ) End Function ' m3uファイル作成 ' @param fileNameには拡張子はつけない ' あらかじめ設定した出力先にfileNameを結合してUNICODEで保存 Function createM3UFile( filePath, fileData ) If Len(fileData) > 0 Then Dim file Set file = fso.OpenTextFile( filePath, 2, True, -1 ) file.Write( fileData ) file.Close createM3UFile = True WScript.Echo "create " & fso.GetAbsolutePathName(filePath) Else createM3UFile = False End If End Function ' パスからドライブ名を除く ' [c:\folder\folder\file.ext]->[\folder\folder\file.ext] Function delDriveName( filePath ) Dim pos pos = InStr( filePath, "\" ) Dim strLen strLen = Len( filePath ) Dim ret ret = Right( filePath, strLen-pos+1 ) delDriveName = ret End Function ' ディレクトリ内にあるwmv, mp3, wav, ogg ファイルのパスをfileDataに列挙。 ' そのときC:などのドライブ名は削除し\Music~といったファイルパスに変換されて保存する Function scanMusicFile( dirObj, fileData, mostNewDate ) Dim fileNum fileNum = 0 Dim fileObj For Each fileObj In dirObj.Files Dim ext ext = LCase( fso.GetExtensionName(fileObj) ) If ext="wmv" Or ext="mp3" Or ext="wav" Or ext="ogg" Then mostNewDate = getMostNewDate( fileObj, mostNewDate ) fileData = fileData & delDriveName( fileObj ) & vbNewLine fileNum = fileNum + 1 End If Next scanMusicFile = fileNum End Function ' ディレクトリ走査 ' 音楽ファイルへのパスをあつめるところまで Sub scanDirectory( dirObj, fileData, mostNewDate, musicFileNum ) mostNewDate = getMostNewDate( dirObj, mostNewDate ) Dim subDirObj For Each subDirObj In dirObj.SubFolders Call scanDirectory( subDirObj, fileData, mostNewDate, musicFileNum ) Next musicFileNum = musicFileNum + scanMusicFile( dirObj, fileData, mostNewDate ) End Sub ' searchDirectoryに定義したパスを走査 Sub scanRootDirectory( dirPath ) Dim src Set src = fso.GetFolder( dirPath ) Dim filePath Dim subDirObj For Each subDirObj In src.SubFolders Dim fileData Dim mostNewDate Dim musicFileNum fileData = "" mostNewDate = subDirObj.DateLastModified musicFileNum = 0 Call scanDirectory( subDirObj, fileData, mostNewDate, musicFileNum ) filePath = createM3UFilePath( fso.GetFileName(subDirObj) ) If needCreatePlayListFile(filePath, mostNewDate, musicFileNum) Then Call createM3UFile( filePath, fileData ) End If Next ' searchDirectoryにある曲をm3u出力する If Len(rootFileName) > 0 Then fileData = "" mostNewDate = src.DateLastModified musicFileNum = scanMusicFile( src, fileData, mostNewDate ) filePath = createM3UFilePath( rootFileName ) If needCreatePlayListFile(filePath, mostNewDate, musicFileNum) Then Call createM3UFile( filePath, fileData ) End If End If End Sub ' 処理の開始 outputDirectory = fso.GetAbsolutePathName( outputDirectory ) searchDirectory = fso.GetAbsolutePathName( searchDirectory ) Dim message message = "処理を開始します" & vbNewLine & "input = " & searchDirectory & vbNewLine & "output = " & outputDirectory If MsgBox(message, 1, "確認")=1 Then Call scanRootDirectory( searchDirectory ) MsgBox("終了") End If
プレイリストの更新が必要ならば書き換えるのだけど、
フォルダのタイムスタンプは曲ファイルを削除やコピーしたときに更新されないので、
フォルダだけでなく曲ファイルのタイムスタンプも見る必要があった。
曲ファイルのタイムスタンプもコピーや削除では更新されないので、
結局、既存のプレイリストがあれば中身を見て、
パスがさすファイルの有無と、曲数が一致しているかをみることで
プレイリストを更新するかどうかを判断した。
全リスト書き換えるより精神衛生はいいが、処理時間は増えたような気がする。
2012年3月24日土曜日
日記ちゃんCheckPlayList
変更のあったものだけプレイリストの書き換えを行うよう修正しようと思ったのだけど、
フォルダの名前変更では更新日時が変更されずスルーしてしまったり、
曲ファイルを削除しただけではフォルダの更新日時が変更されずスルーされたりと、
なかなかうまいこといかない。(削除だとファイルの更新日時もチェックできない。当然だが)
プレイリストの中身を見てファイルがちゃんと存在するかチェックしてやる必要があるのかもしれないが、
いまですら結構処理時間がかかってるだけに踏ん切りがつかないのが現状だ。
本体の起動時にプレイリストをチェックしている節がみられるが、
特にプレイリスト事体編集しているわけではないようだ。
m3uをみてファイルの有無をチェックするプログラムを作ってもいいのかもしれない。
できた。
画像ではIkaruga.m3uの10行目に記述されたパスが存在していない。
https://skydrive.live.com/redir.aspx?cid=8cd7cf5ea9fbca55&resid=8CD7CF5EA9FBCA55!386&parid=8CD7CF5EA9FBCA55!138&authkey=!ADW8M0BZY_1qdTA
CheckPlayList.vbs
size: 2KB
■概要
ZenStyleM100内のプレイリストに記述されている曲ファイルの有無をチェックする
■使い方
お使いのZenStyleM100、あるは親類のルートフォルダに
ダウンロードしたCheckPlayList.vbsを置いて実行してください。
あるいはファイル内のplayListDirをプレイリストのフォルダパスに書き換えて実行してください。
Zen Style M100ではプレイリスト内のパスを
といったようにドライブ名を除去して記述するので、
チェックの際はドライブ名を付けてからファイルの有無確認をする必要があるぐらい。
フォルダの名前変更では更新日時が変更されずスルーしてしまったり、
曲ファイルを削除しただけではフォルダの更新日時が変更されずスルーされたりと、
なかなかうまいこといかない。(削除だとファイルの更新日時もチェックできない。当然だが)
プレイリストの中身を見てファイルがちゃんと存在するかチェックしてやる必要があるのかもしれないが、
いまですら結構処理時間がかかってるだけに踏ん切りがつかないのが現状だ。
本体の起動時にプレイリストをチェックしている節がみられるが、
特にプレイリスト事体編集しているわけではないようだ。
m3uをみてファイルの有無をチェックするプログラムを作ってもいいのかもしれない。
できた。
画像ではIkaruga.m3uの10行目に記述されたパスが存在していない。
https://skydrive.live.com/redir.aspx?cid=8cd7cf5ea9fbca55&resid=8CD7CF5EA9FBCA55!386&parid=8CD7CF5EA9FBCA55!138&authkey=!ADW8M0BZY_1qdTA
CheckPlayList.vbs
size: 2KB
■概要
ZenStyleM100内のプレイリストに記述されている曲ファイルの有無をチェックする
■使い方
お使いのZenStyleM100、あるは親類のルートフォルダに
ダウンロードしたCheckPlayList.vbsを置いて実行してください。
あるいはファイル内のplayListDirをプレイリストのフォルダパスに書き換えて実行してください。
Zen Style M100ではプレイリスト内のパスを
\dir\dir\file.mp3
といったようにドライブ名を除去して記述するので、
チェックの際はドライブ名を付けてからファイルの有無確認をする必要があるぐらい。
' 指定フォルダ内のm3uファイルに記述されたファイルパスをチェック。 ' ファイルが存在しなければ、行数と記述内容を出力する ' ただしZenStyleM100などのドライブ名のないパスを使用したプレイリストに限定 ' auther sumishiro@gmail.com Option Explicit Dim playListDir playListDir = ".\PlayList" Dim fso Set fso = WScript.CreateObject("Scripting.FileSystemObject") ' 指定m3uファイルをチェック。存在しないファイルがあれば標準出力 Sub checkPlayList( fileObj ) Dim file Set file = fso.OpenTextFile( fileObj, 1, False, -1 ) Dim outputStr outputStr = "" Dim lineNo lineNo = 1 Do Until file.AtEndOfStream=True Dim strLine strLine = file.ReadLine() If fso.FileExists(fileObj.Drive & strLine)=False Then outputStr = outputStr & "(" & lineNo & ") " & strLine & vbNewLine End If lineNo = lineNo + 1 Loop file.Close() ' エラーがあればファイル名と行数、行内容などの情報を出力 If Len(outputStr)>0 Then outputStr = "[" & fileObj & "]" & vbNewLine & outputStr WScript.Echo outputStr End If End Sub ' 指定フォルダ以下を走査。m3uがあればチェック Sub searchDir( dir ) Dim subDir For Each subDir In dir.SubFolders Call searchDir( subDir ) Next Dim file For Each file In dir.Files Dim ext ext = LCase( fso.GetExtensionName(file) ) If ext="m3u" Then Call checkPlayList( file ) End If Next End Sub Call searchDir( fso.GetFolder(playListDir) )
2012年3月21日水曜日
日記ちゃん Zen Style M100
10年ほど使っているプレイヤーがフル充電から30分で電池切れするので、
適当にこれ買ったのだけど、これがなかなか癖の強いやつなんだ。
この子、曲をタグで管理するらしく、
いままでフォルダに分けるぐらいしかしてなかったから全部一緒くたにされてしまい目当ての曲を探すのが、もー大変!
そこでフォルダ別のプレイリストを作成するプログラムを書いた。
これなら曲を探しやすいし、管理方法も変えずにすむって寸法。
https://skydrive.live.com/redir.aspx?cid=8cd7cf5ea9fbca55&resid=8CD7CF5EA9FBCA55!385&parid=8CD7CF5EA9FBCA55!138&authkey=!ALp5f6JArx9PAW8
CreatePlayList.vbs
size: 4KB
■使い方
1. お使いのM100のルートフォルダにダウンロードしたCreatePlayList.vbsを置いてください。
2. CreatePlayList.vbsを実行
(windowsならダブルクリックで実行される。ほかは知らん)
確認ウィンドウがでるので良ければ[OK]
3. しばし終わるのを待つ
終わったら[終了]と出ます
その後本体起動時にリストのチェックが入るのか起動時間が長くなります。
気長にお待ちくださいませ。
無事プレイリストの読み込みが完了した
Musicフォルダには以下画像のように配置しています。
完了後のPlayListフォルダはこんな感じに。
■仕様
設定したフォルダパス内にあるフォルダの数だけm3uを作成します。
たとえば、
G:.
├─Music
│ ├─フォルダ1
│ │ ├─01.mp3
│ │ └─02.mp3
│ ├─フォルダ2
│ │ ├─disc1
│ │ │ ├─01.mp3
│ │ │ ├─02.mp3
│ │ │ └─03.mp3
│ │ └─disc2
│ │ ├─01.mp3
│ │ ├─02.mp3
│ │ └─03.mp3
│ └─フォルダ3
├─Pictures
├─Video
├─Recorded
└─Playlist
って構成になっていたら作成されるm3uは
フォルダ1.m3u
フォルダ2.m3u
の2つが、PlayListフォルダに出力されます。
フォルダ2は中にさらにフォルダがありますが、
まとめてフォルダ2.m3uに保存されることになります。
またフォルダ3には曲がないのでフォルダ3.m3uは出力されません。
CreatePlayList.vbsの中身を書き換えることで、
出力先フォルダ、入力フォルダを変更することができます。
デフォルトではPlayListフォルダに出力する設定になっていますが、
既存のプレイリストとごちゃごちゃになるのが気になる方は出力先を変更すると良いでしょう。
以下vbsファイル内容
' Zen Style M100の曲ファイルをフォルダ別にm3uにして、PlayListに保存するプログラム
' 2012-03-21 ver 1.00
' author sumishiro@gmail.com
' 本プログラムのご利用に際し如何なる損失や損害が発生しても、一切の責任を負いかねます。ご了承ください。
Option Explicit
Dim outputDirectory
Dim searchDirectory
Dim rootFileName
' m3u出力先。フォルダが存在しないと出力されないようなので注意
outputDirectory = ".\Playlist"
' 調べるディレクトリパス
' このディレクトリにあるフォルダ名でm3uファイルを作成し、
' 各フォルダ内にある音楽ファイルをm3uに突っ込む
' 同名のm3uは上書きされるので注意
searchDirectory = ".\Music"
' searchDirectory = "./"
' searchDirectoryに直接おいてある曲もm3uリストにしたい場合
' 以下に出力m3uファイル名を定義してね
' rootFileName = "root"
Dim fso
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
' m3uファイル作成
' あらかじめ設定した出力先にfileNameを結合してUNICODEで保存
Function createM3UFile( fileName, fileData )
If Len(fileData) > 0 Then
Dim filePath
filePath = fso.BuildPath( outputDirectory, fileName & ".m3u" )
Dim file
Set file = fso.OpenTextFile( filePath, 2, True, -1 )
file.Write( fileData )
file.Close
createM3UFile = True
Else
createM3UFile = False
End If
End Function
' パスからドライブ名を除く
' [c:\folder\folder\file.ext]->[\folder\folder\file.ext]
Function delDriveName( filePath )
Dim pos
pos = InStr( filePath, "\" )
Dim strLen
strLen = Len( filePath )
Dim ret
ret = Right( filePath, strLen-pos+1 )
delDriveName = ret
End Function
' ディレクトリ内にあるwmv, mp3, wav, ogg, flacファイルのパスをfileDataに列挙。
' そのときC:などのドライブ名は削除し\Music~といったファイルパスに変換されて保存する
Sub scanMusicFile( dirPath, fileData )
Dim src
Set src = fso.GetFolder( dirPath )
Dim filePath
For Each filePath In src.Files
Dim ext
ext = LCase( fso.GetExtensionName(filePath) )
If ext="wmv" Or ext="mp3" Or ext="wav" Or ext="ogg" Or ext="flac" Then
fileData = fileData & delDriveName( filePath ) & vbNewLine
End If
Next
End Sub
' ディレクトリ走査
' 音楽ファイルへのパスをあつめるところまで
Sub scanDirectory( dirPath, fileData )
Dim src
Set src = fso.GetFolder( dirPath )
Dim subDirPath
For Each subDirPath In src.SubFolders
Call scanDirectory( subDirPath, fileData )
Next
Call scanMusicFile( dirPath, fileData )
End Sub
' searchDirectoryに定義したパスを走査
Sub scanRootDirectory( dirPath )
Dim src
Set src = fso.GetFolder( dirPath )
Dim subDirPath
For Each subDirPath In src.SubFolders
Dim fileData
fileData = ""
Call scanDirectory( subDirPath, fileData )
Dim fileName
fileName = fso.GetFileName( subDirPath )
Call createM3UFile( fileName, fileData )
Next
' searchDirectoryにある曲をm3u出力する
If Len(rootFileName) > 0 Then
fileData = ""
Call scanMusicFile( dirPath, fileData )
Call createM3UFile( rootFileName, fileData )
End If
End Sub
' 処理の開始
Dim message
message = "処理を開始します" & vbNewLine & "output=" & fso.GetAbsolutePathName(outputDirectory) & vbNewLine & "input=" & fso.GetAbsolutePathName(searchDirectory)
If MsgBox(message, 1, "確認")=1 Then
Call scanRootDirectory( searchDirectory )
MsgBox("終了")
End If
普段は全曲シャッフルで聞くから問題ないんだけど、
ときどき狙って聞きたくなる。そんな時用。
製作時間二日。WSHは初めてだったが資料が豊富で学びやすい印象だ。
M100はoggの再生が一応可能だが、
バッファリングがうまくいってないのかぶつぶつ途切れがちになるし、
ボタンの反応も悪くなるので使用はあまりお勧めできない。
自分は普段ogg使ってたけど、mp3に変換しなおした。mp3なら快適。
oggでもディスプレイが表示されてないときはぼちぼち再生可能なようだが。
指紋がかなりつくが気にしたら負けだ。
■関連
生産がす: ZenStyleM100-CreatePlayList v102
生産がす: 日記ちゃんCheckPlayList
2012年3月11日日曜日
日記ちゃん
現在のActiveWindowRecorderの仕様では、
ウィンドウタイトルの保存に256Byte使っていてメモリに無駄がある。
そこでウィンドウタイトルの長さ分だけメモリを確保して使用メモリ量を減らそうと考えた。
newで確保する仕様でいったん組んだんだけど、これはこれでメモリが断片化しそうだ。
一日分のウィンドウタイトルのログは追記されていくだけで途中で削除や挿入はされないから
vectorのpush_backを使えば、メモリを一箇所に固められ、
保存するときもそのまま吐き出せばいいから便利ね!
と思いついて実装しているがドはまりした。
難航なう。
解決した。メモリ管理部分の記述ミスとかありがち。
ウィンドウタイトルの保存に256Byte使っていてメモリに無駄がある。
そこでウィンドウタイトルの長さ分だけメモリを確保して使用メモリ量を減らそうと考えた。
newで確保する仕様でいったん組んだんだけど、これはこれでメモリが断片化しそうだ。
一日分のウィンドウタイトルのログは追記されていくだけで途中で削除や挿入はされないから
vectorのpush_backを使えば、メモリを一箇所に固められ、
保存するときもそのまま吐き出せばいいから便利ね!
と思いついて実装しているがドはまりした。
難航なう。
解決した。メモリ管理部分の記述ミスとかありがち。
2012年3月9日金曜日
日記ちゃん虫姫さま360
アレンジはアレンジのままなのね。
ノービス追加とグラ書き直しがPS2版との違いになる。
初回特典に1.5。アレンジ曲枠も1.5に使われるのかも。
マキシマムも7日に発売され
youtubeにもいくつか動画がすでにアップされてる模様。
弾が大きいからか地味に違和感を覚えるが携帯機の宿命だろうか。
2012年3月2日金曜日
日記ちゃん
std::vector<int> v;
...
v.push_back( 100 );
int* p = &v[0];
v.push_back( 110 );
*p = 120;
みたいなことして死んでた。
push_backで追加して、ひょっこりバッファが確保されなおされると
当然アドレスが変わってるので死ぬっつーオチ。
...
v.push_back( 100 );
int* p = &v[0];
v.push_back( 110 );
*p = 120;
みたいなことして死んでた。
push_backで追加して、ひょっこりバッファが確保されなおされると
当然アドレスが変わってるので死ぬっつーオチ。
登録:
投稿 (Atom)