はみ出しRAPTの戯言

- a day after yesterday -

目次

Blog 利用状況

ニュース

書庫

日記カテゴリ

コミュニティ リンク

2010年4月26日 #

Gavotte Ramdisk を Windows 7 x64 で使う

概要

Windows 7 x64 環境で、フリーの Gavotte Ramdisk を使いたい。
ところが、Gavotte Ramdisk のドライバは署名されていないので、そのままでは x64 環境にインストールできない。
巷にはブート中に自動的に [F8] を押して、ドライバの署名を無視して、といった手法がみられるが、これはやりたくない。
そのため、オレオレ証明書を作り、自己署名することでドライバのインストールブロッキングを回避する。
x64 用ドライバは、rramdisk64.sys なので、これを署名する。
下記で、署名パスワードは "hogehoge" にしているので、適宜変更すること。
※Vista 以降の環境では、コマンドプロンプトを「管理者として実行」にする必要あり。

ドライバを署名する

  1. Windows® Server 2003 SP1 Platform SDK Web Install に含まれている署名ツールをインストール
  2. 証明書(.cer)と秘密鍵(.pvk)を作る(パスワードはすべて同一のものを指定)
    makecert -sv rramdisk64.pvk -a sha1 -eku 1.3.6.1.5.5.7.3.3 -r -ss Root -len 1024 -sr localMachine -n CN="rramdisk64.sys" rramdisk64.cer
    -keu 1.3.6.1.5.5.7.3.3 はコード署名
    CN="xxxx" は発行元
  3. 証明書(.cer)からソフトウェア発行元証明書(.spc)ファイルを作る
    cert2spc rramdisk64.cer rramdisk64.spc
  4. ソフトウェア発行元証明書(.spc)と秘密鍵(.pvk)からキーペア(.pfx)ファイルを作る
    pvk2pfx -pvk rramdisk64.pvk -pi hogehoge -spc rramdisk64.spc -pfx rramdisk64.pfx
  5. 署名ツールでターゲットファイルに電子署名する
    signtool sign /f rramdisk64.pfx /p hogehoge /d "rramdisk64.sys" /v rramdisk64.sys

証明書のインストール

  1. rramdisk64.pfx を右クリックして「インストール」
  2. [パスワード] で hogehoge を入力し、「すべての拡張プロパティを含める」にチェック
  3. [証明書ストア] で「証明書をすべて次のストアに配置する」にチェック
  4. 「物理ストアを表示する」にチェック
  5. 「信頼されたルート証明機関\レジストリ」を選択

ドライバのインストール

  1. ram4g.reg をダブルクリックしてインストール
  2. 管理者権限で、普通にコマンドプロンプトを出す
  3. ブート構成データ エディタで、デジタル署名取得を無効化する
    bcdedit /set TESTSIGNING ON
  4. PC を再起動
  5. 「ファイル名を指定して実行」で hdwwiz を入力し、ハードウェアの追加ウィザードを開く
  6. 「一覧から選択したハードウェアをインストールする」にチェックし「次へ」
  7. 「すべてのデバイスを表示」を選択して「次へ」
  8. 「ディスク使用」をクリック
  9. 「製造元のファイルのコピー元」で上記で証明した rramdisk64.sys のあるフォルダを指定
  10. これで次々と表示される警告にめげずにクリックしていくと成功

Ramdisk の作成

  1. ramdisk.exe を右クリックして「管理者として実行」
  2. 「Install Ramdisk」をクリック
  3. 今回は RamDisk を 5GB 使いたいので「Data Size」に「5G」と入力。プルダウンには 3G までしかないが、手入力 OK
  4. 「Drive Letter」も「R:」のままでいいので、そのまま
  5. Media Type も「Fixed Media」のままで OK
  6. 「OK」をクリック
  7. PC を再起動

これで無事に RAM ドライブが使えるようになりました(^^

posted @ 15:24 | Feedback (2)

2010年4月22日 #

Windows 7 のタスクスケジューラでバッチファイルを実行する

今まで Windows XP のタスクスケジューラで、毎日一定時刻にバックアップを取るようにしていたが、
PC の劣化に伴い、データ載せ替えの際、OS を Windows 7 にした。

データの移行は、NIC 同時を LAN ケーブルでつないで、手動で IP アドレスを設定し、フォルダ共有で
ファイルを受け渡しするという単純作業で楽にできた。

タスクスケジューラで使用していたバッチファイルもコピーし、なんとなくタスクを設定してみたが、
翌朝動作を確認したら、コピーできていなかった。

ここで、散々設定を見直したり、ヘルプを見たり、ググったりしてみたが、一向に解決できず。

丸一日かけてどうやら解決策が判明したっぽいので備忘録として記す。
かなりハマった上に、情報の少なさときたら!
とりあえず色々と試行錯誤したところ、下記でうまくいった。

タスクスケジューラの起動:[スタート]-[管理ツール]-[タスク スケジューラ]

新しいタスクの作成:
[全般] タブ:
[名前] には分かりやすい名前を。「夜間バックアップ」とか。。
(後で変更できないっぽい。C:\Windows\System32\Tasks にあるファイル名を変更すれば可能? 未検証。)
(※[最上位の特権で実行する] にチェックを入れると、バッチファイル内でフォルダを作ったりするとアクセス権が設定されてしまう。)

[全般] タブ:
[ユーザーがログオンしているかどうかにかかわらず実行する]?にチェック

[トリガー] タブ:
[新規] で、[スケジュールに従う] / [毎日] / [有効]

[操作] タブ:
[プログラムの開始]
[プログラム/スクリプト] に実行したいバッチファイルのフルパス ("C:\Program Files (x86)\FastCopy\NightlyBackup.bat" など)
[開始(オプション)] に上記で指定したバッチファイルの作業フォルダを入れる。※パスにスペースがあったとしても、ここではダブルクォーテーションを入れてはダメ

[履歴] タブは規定では無効となっているが、タスクスケジューラのメイン画面右側にある「操作」ウィンドウ内の「すべてのタスク履歴を有効にする」を選択することで有効になる。
(※この設定はここ以外からは設定できなさげ。起動時のウィンドウサイズでは、ここのテキストが省略され、読めなくなっていたため、ヘルプを見てもどこに設定があるか見つけられなかった。)

上記まで入力後、OK ボタンを押下すると、実行ユーザーの認証用パスワードを要求され、正しく入力するとタスクが正常に追加される。

追加したタスクの有効/無効の切り替えなどは、プロパティを開いても変更できるが、先ほどの「操作」ウィンドウで変更した方が便利。

?

さて、これでうまくいくはずだ。

posted @ 16:27 | Feedback (0)

2009年1月14日 #

IE7 以降で HttpOpenRequest() API が エラーコード 12006 で失敗する件

IE7 以降で HttpOpenRequest() API が エラーコード 12006 で失敗する件

プログラム上からインターネットに接続して直接ファイルをダウンロードしたい場合などに、InternetOpen/InternetConnect/HttpOpenRequest API を使って下記のようなコードを使用すると思うが、このコードは IE6 以前では問題なく動作するが、IE7 以降では失敗する。

HINTERNET hSession = ::InternetOpen( _T( "UserAgent" ), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0 );
HINTERNET hConnect = ::InternetConnect( hSession, _T( "www.example.com" ), 80, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 );
HINTERNET hRequest = ::HttpOpenRequest( hConnect, _T( "GET" ), _T( "/~user/path/file.txt" ), NULL, _T( "Referrer" ), NULL, INTERNET_FLAG_DONT_CACHE, 0 );
if ( hRequest == NULL ) {
    DWORD dwError = ::GetLastError();
    if ( dwError == ERROR_INTERNET_UNRECOGNIZED_SCHEME /*12006*/ ) {
        ATLTRACE( _T( "スキームが認識できないエラー\n" ) );
    }
}

// (snip)

::InternetCloseHandle( hRequest );
::InternetCloseHandle( hConnect );
::InternetCloseHandle( hSession );

原因は、HttpOpenRequest() でリファラに「Referrer」と記述しているがこの形式が「スキーム:識別子」の形式になっていないことによるものらしい。これをたとえば「myscheme:Referrer」に変更することで上記コードは IE7 以降でも正常に動作する。

なぜ IE7 以降で動作しなくなったかは不明だが、これにはかなりハマったので記事にして残しておくことにした。

posted @ 2:51 | Feedback (1)

IE8 Beta2 で User-Agent が変更できない問題

IE8 Beta2 で User-Agent が変更できない問題

今更ネタにするものでもないけど、去年の夏に IEβニュースグループに投稿した記事と同じ内容をここにも書いておく。

VC6/VC2003 で Trident コンポーネントを使っプログラムを作成しているときの話。
プログラム上で User-Agent を変更して接続するために UrlMkSetSessionOption( URLMON_OPTION_USERAGENT ) API を使用しているが、IE8β2 では正常に動作しない。

下記のサンプルコードは IE4 以降の環境では正常に動作するが、IE8 では UrlMkSetSessionOption は正常終了(S_OK) を返すものの効果がない。

void ChangeUserAgentTest()
{
    char lpaUserAgent[ 1024 ] = "test user-agent";
    DWORD dwLength = lstrlenA( lpaUserAgent );
    HRESULT hr = ::UrlMkSetSessionOption( URLMON_OPTION_USERAGENT, lpaUserAgent, dwLength, 0 );
    CString strMsg;
    strMsg.Format( _T( "UrlMkSetSessionOption: 0x%08x" ), hr );
    ::MessageBox( NULL, strMsg, _T( "[debug - 1]" ), MB_OK );
    if ( hr == S_OK ) {
        DWORD dwSize = 1023;
        char lpaString[ 1024 ] = {0};
        hr = ::ObtainUserAgentString( 0, lpaString, &dwSize );
        strMsg.Format( _T( "ObtainUserAgentString: 0x%08x\n%s" ), hr, CString( lpaString ) );
        ::MessageBox( NULL, strMsg, _T( "[debug - 2]" ), MB_OK );
    }
}

最初のメッセージは成功を返す。
---------------------------
[debug - 1]
---------------------------
UrlMkSetSessionOption: 0x00000000
---------------------------
OK
---------------------------

二番目ののメッセージも成功を返す。
---------------------------
[debug - 2]
---------------------------
ObtainUserAgentString: 0x00000000
test user-agent
---------------------------
OK
---------------------------

しかしながら、ウェブサイトにアクセスすると、サーバー変数は下記の値を返す:
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0)

IE8 より前では下記の値を返す:
test user-agent

ひょっとしたら IE8 以降で User-Agent を変更するための手順が変更されたのか、とも思ったがバグの可能性が高い。

この API は、urlmon.dll に含まれているため、一般プログラマからは何もできなさげ。
正式版までに解決してくれていることを願うばかり。

posted @ 2:21 | Feedback (5)

2008年8月17日 #

INI 編集ツール IniModifier を作成してみる (3)

INI 編集ツール IniModifier を作成してみる (3)

過去の記事へのリンク:
INI 編集ツール IniModifier を作成してみる (1)
INI 編集ツール IniModifier を作成してみる (2)

まずは、WTL::CRichEditCtrl のヘッダを見てみることにする。
WTL は SDK のラッパであり、MFC とほぼ同機能のメソッドを持っているので迷ったら、MSDN で MFC と SDK のヘルプを見るのが常套手段。

WTL::CRichEditCtrl

// WTL::CRichEditCtrl (CRichEditCtrlT<ATL::CWindow>) の宣言
// Constructors
    CRichEditCtrl( HWND hWnd = NULL );
    CRichEditCtrl& operator =( HWND hWnd );
    HWND Create( HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
            DWORD dwStyle = 0, DWORD dwExStyle = 0,
            ATL::_U_MENUorID MenuOrID = 0U, LPVOID lpCreateParam = NULL );

// Attributes
    static LPCTSTR GetWndClassName();
    static LPCTSTR GetLibraryName();

    int GetLineCount() const;
    BOOL GetModify() const;
    void SetModify( BOOL bModified = TRUE );
    void GetRect( LPRECT lpRect ) const;
    DWORD GetOptions() const;
    DWORD SetOptions( WORD wOperation, DWORD dwOptions );

    // NOTE: first word in lpszBuffer must contain the size of the buffer!
    int GetLine( int nIndex, LPTSTR lpszBuffer ) const;

    int GetLine( int nIndex, LPTSTR lpszBuffer, int nMaxLength ) const;
    BOOL CanUndo() const;
    BOOL CanPaste( UINT nFormat = 0 ) const;
    void GetSel( LONG& nStartChar, LONG& nEndChar ) const;
    void GetSel( CHARRANGE &cr ) const;
    int SetSel( LONG nStartChar, LONG nEndChar );
    int SetSel( CHARRANGE &cr );
    int SetSelAll();
    int SetSelNone();
    DWORD GetDefaultCharFormat( CHARFORMAT& cf ) const;
    DWORD GetSelectionCharFormat( CHARFORMAT& cf ) const;
    DWORD GetEventMask() const;
    LONG GetLimitText() const;
    DWORD GetParaFormat( PARAFORMAT& pf ) const;

#if ( _RICHEDIT_VER >= 0x0200 )
    LONG GetSelText( LPTSTR lpstrBuff ) const;
#else
    // RichEdit 1.0 EM_GETSELTEXT is ANSI only
    LONG GetSelText( LPSTR lpstrBuff ) const;
#endif

#ifndef _ATL_NO_COM
    BOOL GetSelTextBSTR( BSTR& bstrText ) const;
#endif

#if defined( _WTL_USE_CSTRING ) || defined( __ATLSTR_H__ )
    LONG GetSelText( _CSTRING_NS::CString& strText ) const;
#endif

    WORD GetSelectionType() const;
    COLORREF SetBackgroundColor( COLORREF cr );
    COLORREF SetBackgroundColor();    // sets to system background
    BOOL SetCharFormat( CHARFORMAT& cf, WORD wFlags );
    BOOL SetDefaultCharFormat( CHARFORMAT& cf );
    BOOL SetSelectionCharFormat( CHARFORMAT& cf );
    BOOL SetWordCharFormat( CHARFORMAT& cf );
    DWORD SetEventMask( DWORD dwEventMask );
    BOOL SetParaFormat( PARAFORMAT& pf );
    BOOL SetTargetDevice( HDC hDC, int cxLineWidth );
    int GetTextLength() const;
    BOOL SetReadOnly( BOOL bReadOnly = TRUE );
    int GetFirstVisibleLine() const;
    EDITWORDBREAKPROCEX GetWordBreakProcEx() const;
    EDITWORDBREAKPROCEX SetWordBreakProcEx( EDITWORDBREAKPROCEX pfnEditWordBreakProcEx );
    int GetTextRange( TEXTRANGE* pTextRange ) const;

#if ( _RICHEDIT_VER >= 0x0200 )
    int GetTextRange( LONG nStartChar, LONG nEndChar, LPTSTR lpstrText ) const;
#else
    int GetTextRange( LONG nStartChar, LONG nEndChar, LPSTR lpstrText ) const;
#endif

#if ( _RICHEDIT_VER >= 0x0200 )
    DWORD GetDefaultCharFormat( CHARFORMAT2& cf ) const;
    BOOL SetCharFormat( CHARFORMAT2& cf, WORD wFlags );
    BOOL SetDefaultCharFormat( CHARFORMAT2& cf );
    DWORD GetSelectionCharFormat( CHARFORMAT2& cf ) const;
    BOOL SetSelectionCharFormat( CHARFORMAT2& cf );
    BOOL SetWordCharFormat( CHARFORMAT2& cf );
    DWORD GetParaFormat( PARAFORMAT2& pf ) const;
    BOOL SetParaFormat( PARAFORMAT2& pf );
    TEXTMODE GetTextMode() const;
    BOOL SetTextMode( TEXTMODE enumTextMode );
    UNDONAMEID GetUndoName() const;
    UNDONAMEID GetRedoName() const;
    BOOL CanRedo() const;
    BOOL GetAutoURLDetect() const;
    BOOL SetAutoURLDetect( BOOL bAutoDetect = TRUE );

    // this method is deprecated, please use SetAutoURLDetect
    BOOL EnableAutoURLDetect( BOOL bEnable = TRUE );

    UINT SetUndoLimit( UINT uUndoLimit );
    void SetPalette( HPALETTE hPalette );
    int GetTextEx( GETTEXTEX* pGetTextEx, LPTSTR lpstrText ) const;
    int GetTextEx( LPTSTR lpstrText, int nTextLen, DWORD dwFlags = GT_DEFAULT, UINT uCodePage = CP_ACP, LPCSTR lpDefaultChar = NULL, LPBOOL lpUsedDefChar = NULL ) const;
    int GetTextLengthEx( GETTEXTLENGTHEX* pGetTextLengthEx ) const;
    int GetTextLengthEx( DWORD dwFlags = GTL_DEFAULT, UINT uCodePage = CP_ACP ) const;
#endif

#if ( _RICHEDIT_VER >= 0x0300 )
    int SetTextEx( SETTEXTEX* pSetTextEx, LPCTSTR lpstrText );
    int SetTextEx( LPCTSTR lpstrText, DWORD dwFlags = ST_DEFAULT, UINT uCodePage = CP_ACP );
    int GetEditStyle() const;
    int SetEditStyle( int nStyle, int nMask = -1 );
    BOOL SetFontSize( int nFontSizeDelta );
    void GetScrollPos( LPPOINT lpPoint ) const;
    void SetScrollPos( LPPOINT lpPoint );
    BOOL GetZoom( int& nNum, int& nDen ) const;
    BOOL SetZoom( int nNum, int nDen );
    BOOL SetZoomOff();
#endif

// Operations
    void LimitText( LONG nChars = 0 );
    int LineFromChar( LONG nIndex ) const;
    POINT PosFromChar( LONG nChar ) const;
    int CharFromPos( POINT pt ) const;
    void EmptyUndoBuffer();
    int LineIndex( int nLine = -1 ) const;
    int LineLength( int nLine = -1 ) const;
    BOOL LineScroll( int nLines, int nChars = 0 );
    void ReplaceSel( LPCTSTR lpszNewText, BOOL bCanUndo = FALSE );
    void SetRect( LPCRECT lpRect );
    BOOL DisplayBand( LPRECT pDisplayRect );
    LONG FindText( DWORD dwFlags, FINDTEXT& ft ) const;
    LONG FindText( DWORD dwFlags, FINDTEXTEX& ft ) const;
    LONG FormatRange( FORMATRANGE& fr, BOOL bDisplay = TRUE );
    LONG FormatRange( FORMATRANGE* pFormatRange, BOOL bDisplay = TRUE );
    void HideSelection( BOOL bHide = TRUE, BOOL bChangeStyle = FALSE );
    void PasteSpecial( UINT uClipFormat, DWORD dwAspect = 0, HMETAFILE hMF = 0 );
    void RequestResize();
    LONG StreamIn( UINT uFormat, EDITSTREAM& es );
    LONG StreamOut( UINT uFormat, EDITSTREAM& es );
    DWORD FindWordBreak( int nCode, LONG nStartChar );

    // Additional operations
    void ScrollCaret();
    int InsertText( long nInsertAfterChar, LPCTSTR lpstrText, BOOL bCanUndo = FALSE );
    int AppendText( LPCTSTR lpstrText, BOOL bCanUndo = FALSE );

    // Clipboard operations
    BOOL Undo();
    void Clear();
    void Copy();
    void Cut();
    void Paste();

    // OLE support
    IRichEditOle* GetOleInterface() const;
    BOOL SetOleCallback( IRichEditOleCallback* pCallback );

#if ( _RICHEDIT_VER >= 0x0200 )
    BOOL Redo();
    void StopGroupTyping();
    void ShowScrollBar( int nBarType, BOOL bVisible = TRUE );
#endif

#if ( _RICHEDIT_VER >= 0x0300 )
    BOOL SetTabStops( int nTabStops, LPINT rgTabStops );
    BOOL SetTabStops();
    BOOL SetTabStops( const int& cxEachStop );    // takes an 'int'
#endif

これで大体何ができるか分かった。 あとは、実際に使用しそうで使ったことがないメソッドについて詳しくみていくことにする。

GetLibraryName

リッチエディットコントロールを使用するには、最初にリッチエディットコントロールの DLL をロードしておかなければいけないらしい。
リッチエディットコントロールの DLL 名はバージョンによって異なるので(Ver1.0 は RICHED32.DLL で、Ver2.0 以降は RICHED20.DLL)、このメソッドを使うことでその違いを CRichEditCtrl がプリプロセス時点で解決してくれる。

// IniModifier.cpp
int WINAPI _tWinMain( HINSTANCE, HINSTANCE, LPTSTR, int )
{
    HMODULE hRich = ::LoadLibrary( CRichEditCtrl::GetLibraryName() );

    // snip

    ::FreeLibrary( hRich );

    return nRet;
}

SetSelectionCharFormat

現在の選択のテキストの文字書式属性を設定する。
なお、選択範囲がない場合は、以降の入力についての設定となる。

// CRichEditCtrl m_rich;

// テキストを青色太字にして保護にする
CHARFORMAT cf;
cf.dwMask = CFM_PROTECTED | CFM_COLOR | CFM_BOLD;
cf.dwEffects = CFE_PROTECTED | CFE_BOLD;
cf.crTextColor = RGB( 0, 0, 255 );
m_rich.SetSelectionCharFormat( cf );

SetEventMask

親ウィンドウに送る通知メッセージを指定する。

ENM_PROTECTED
保護領域を編集しようとした時に WM_NOTIFY メッセージで EN_PROTECTED が通知されるようにする。
0 を返すと変更許可、非0 を返すと変更禁止とする。
ENPROTECTED* pProtected = reinterpret_cast< ENPROTECTED* >( reinterpret_cast< LPNMHDR >( lParam ) ); としたとき、
pProtected->msg に、この通知発生原因のメッセージ ID が入っている。
pProtected->chrg.cpMinpProtected->chrg.cpMax に、この通知発生元のインデックス(リッチエディットコントロール先頭位置からのオフセット)が入っている。
ENM_KEYEVENTS
キーボードイベントが発生した時に WM_NOTIFY メッセージで EN_MSGFILTER が通知されるようにする。
0 を返すと通常のイベントを処理する。非0 を返すと以降のイベント処理を無視する。
MSGFILTER* pFilter = reinterpret_cast< MSGFILTER* >( reinterpret_cast< LPNMHDR >( lParam ) ); としたとき、
pFilter->msg に、この通知発生原因のメッセージ ID が入っている。
ENM_MOUSEEVENTS
マウスイベントが発生した時に WM_NOTIFY メッセージで EN_MSGFILTER が通知されるようにする。
EN_MSGFILTER の動作については、ENM_KEYEVENTS と同じ。
m_rich.SetEventMask( ENM_PROTECTED | ENM_KEYEVENTS | ENM_MOUSEEVENTS );

posted @ 16:20 | Feedback (0)

2008年8月16日 #

INI 編集ツール IniModifier を作成してみる (2)

INI 編集ツール IniModifier を作成してみる (2)

過去の記事へのリンク:
INI 編集ツール IniModifier を作成してみる (1)

リソース配置が楽なのでダイアログベースで作ることにする。
とりあえずリソースエディタで適当にコントロールを配置して、UI を決める。
ダイアログの自動リサイズを実装するため、CDialogResize も継承しておく。

class CMainDlg
    : public CDialogImpl< CMainDlg >
    , public CDialogResize< CMainDlg >
{

テキストを編集したり色をつけたりしたいので、リッチエディットコントロールを使ってみようと思う。リッチエディットコントロールを使うのはこれが初めてだが、WTL のヘッダを見ていると結構いろいろできそうなので、せっかくなので調べながら作っていくことにする。

リソースエディタのイメージはこんな感じ↓

リソースエディタのイメージ

リッチエディットコントロールは 2.0 を使うこととする。
CDialogResize は atlframe.h
CRichEditCtrl は atlctrls.h
にそれぞれ定義されているので、stdafx.h は下記のようになった。

// stdafx.h
// Change these values to use different versions
#define WINVER          0x0500
#define _WIN32_WINNT    0x0501
#define _WIN32_IE       0x0501
#define _RICHEDIT_VER   0x0200

// WTL よりも ATL を優先する場合は、atlapp.h より前に include すること
#include <atlstr.h>
#include <atltypes.h>

#include <atlbase.h>
#include <atlapp.h>

extern CAppModule _Module;

#include <atlcrack.h>

#include <atlframe.h>  // CDialogResize
#include <atlctrls.h>  // CRichEditCtrl
#include <atldlgs.h>   // CFileDialog

処理の関係上、文字セットは UNICODE ではなく、マルチバイト文字セット(MBCS) でビルドすることにする。

// stdafx.cpp
#if defined( _UNICODE ) || defined( UNICODE )
#error This program doesn't assume unicode build.
#endif

# ところで、なぜ #error ディレクティブではマルチバイト文字が使えないんだろ。
# ダブルクォーテーションで括ってやってもだめ。L"" としてもだめ。何かうまくいくようにしてくれるといいんだけど。

posted @ 1:23 | Feedback (1)

INI 編集ツール IniModifier を作成してみる (1)

IniModifier

Inno Setup のフロントエンドである ISTool の日本語言語ファイル作成をしたりしているが、INI 形式のファイルをアップデートが非常にめんどくさすぎるので何かツールを作成しようと思う。

開発環境は以下の通り。

  • Windows XP sp2
  • Visual C++ .NET 2003 sp1
  • WTL 8.0

要件仕様は下記の通りとする。

  • ファイルのエンコーディングは SJIS/UTF-8 に対応。(できれば EUC も対応。)
  • セクション名・キー名で差分チェックを行う。
  • Visual SourceSafe の比較画面のように見比べつつ編集もできるようにする。
  • セクション:[太字表示]
  • コメント:緑色表示
  • 追加されたセクション・キー:青色表示
  • 削除されたセクション・キー:赤色表示
  • 削除されたキー:キーの先頭に ";<DEL>:" を追加。

IniModifier の完成イメージはこんな感じ↓

IniModifier の完成イメージ

posted @ 0:18 | Feedback (6)

2008年3月21日 #

2008年02月度PageView

とっても今更感がありますが・・・(^^;

2008年02月度PageView
日付PV
合計12,270
平均423
前月比+0.3%
2008/02/01386
2008/02/02257
2008/02/03*448
2008/02/04513
2008/02/05433
2008/02/06435
2008/02/07437
2008/02/08474
2008/02/09267
2008/02/10374
2008/02/11791
2008/02/12529
2008/02/13571
2008/02/14388
2008/02/15370
2008/02/16312
2008/02/17291
2008/02/18*707
2008/02/19*790
2008/02/20554
2008/02/21379
2008/02/22416
2008/02/23228
2008/02/24270
2008/02/25372
2008/02/26305
2008/02/27374
2008/02/28302
2008/02/29297

記事を投稿した日に * 印をつけてみました。

IME 関係の記事はまま好評だったようで何より。

posted @ 23:42 | Feedback (0)

2008年3月4日 #

ウイルスバスター 2008 の落とし穴

自宅では、メーラーは秀丸メールを使用しているのだけど、大量にくる迷惑メールはウイルスバスター 2007 の迷惑/詐欺メールの判定機能([MEIWAKU] や [Phishing] と件名に表示)を併用してうまくフィルタリングさせていた。

ところが 3/1 に自宅のウイルスバスターを 2008 にアップデートしたところ、深刻な問題が発生。迷惑メール対策機能を設定しているにも関わらず、上記の [MEIWAKU] といった文字が追加されなくなり、メールのフィルタリングが動作しなくなってしまった

何度か設定を見直したが、設定ミスというのは考えられず、むしろ機能削除された感がある。そこで、サポートにメール問い合わせをしてみた。

以下、回答。
----------
迷惑/詐欺メールの判定につきまして、[MEIWAKU]や[Phishing]と件名に表示という機能は
大変申し訳ございませんがご要望されている機能は
現時点では、ウイルスバスター2008 にはにはございません。

ご希望に添うことができず、誠に申し訳ございませんが製品仕様につき
なにとぞご理解、ご了承のほどよろしくお願いいたします。

なお、「秀丸メール」は動作要件外となっております。
大変申し訳ございませんが、何卒ご了承いただきますようお願いいたします。
----------

とのことorz

いやな予感、大的中。速攻で 2007 に戻しました。
この迷惑メール判定機能が便利でアッサリ 3 年契約したのに・・・
とりあえず再登載の要望は出しておくか。

年内は 2007 が使えるからいいとして、来年からどうしようかな。
こうなってはウイルスバスター 2008 は もはや使う意味ないし、何かいいフィルタリングソフトを探さないといけないかな。。

posted @ 23:48 | Feedback (6)

2008年2月19日 #

Microsoft Office IME 2007 で [JP] から [EN] に変わっってしまったときの直しかた

キーボードの A を押すと半角カナの「チ」となってしまうときの直しかた でいただいたコメントより。

[Alt+Shift] で [EN] - [JP] 間の切り替えができました。
これで、万一言語が切り替わってしまっても、いちいちキーボードから手を離さずにそのまま入力を続けることができます。

2リットルさん、情報ありがとうございました。

posted @ 10:10 | Feedback (2)