[スレッド全体]

2014/4/20 (日) 17:50:43 novice  
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0
[2155] Re3:不具合:「開きません」のキャンセルが存在しません
▼ 神楽さん
Unicode版は、r1587でキャンセルが削除されたようです。
http://sourceforge.net/p/sakura-editor/code/1587/

PatchUnicodeは未登録で、掲示板にログが残ってましたが、キャンセルの削除については特に記載が見つかりませんでした。
http://sakura-editor.sourceforge.net/cgi-bin/cyclamen/cyclamen.cgi?log=unicode&v=950

2014/5/8 (木) 06:21:50 神楽  
Mozilla/5.0 (X11; Linux x86_64; rv:29.0) Gecko/20100101 Firefox/29.0
[2165] Re4:不具合:「開きません」のキャンセルが存在しません
▼ noviceさん
2.1.1.1も同じ挙動だったのですが、2.1.1.2で文字コード情報の
メッセージダイアログがアクティブの時に、
Ctrl+Cでダイアログタイトルバー通りの「文字コード情報」とコピーされず、
「(保存されていません)」と「(印刷プレビューでのみ使用できます)」が
Ctrl+Cする度に、交互に繰り返されます。
1.6.6.0ではタイトルバー通りにコピーされますので、できれば対策をお願い致します。

2014/5/8 (木) 20:38:59 LR4  
Mozilla/5.0 (Windows NT 6.1; rv:29.0) Gecko/20100101 Firefox/29.0
[2166] Re5:不具合:「開きません」のキャンセルが存在しません
ちゃんと検証したわけではないのでアレですが…

> 「(保存されていません)」と「(印刷プレビューでのみ使用できます)」が
> Ctrl+Cする度に、交互に繰り返されます。


これ、メッセージボックス出しているときにエディタウィンドウのアクティブ/非アクティブ切替が発生し、
CEditWnd::UpdateCaption()
 → CSakuraEnvironment::ExpandParameter()
が呼ばれてメッセージバッファの書き換え(CLoadStringでのバッファリサイクル)が起きているせいではないでしょうか。

メッセージボックス上でCtrl+Cされるたびに、MessageBox APIが引数の文字列ポインタを直接参照しているのかな?、と思うわけです。
メッセージ本文のほうが無事なのは、MYMESSAGEBOXが本文を別のバッファにコピーしてMessageBox APIに渡しているからかも。

2014/5/9 (金) 17:42:18 LR4  
Mozilla/5.0 (Windows NT 6.1; rv:29.0) Gecko/20100101 Firefox/29.0
[2168] Re6:不具合:「開きません」のキャンセルが存在しません
> メッセージ本文のほうが無事なのは、MYMESSAGEBOXが本文を別のバッファにコピーしてMessageBox APIに渡しているからかも。

案の定、[共通設定]-[強調キーワード]の[整理]ボタンを押したときに
表示されるメッセージボックスで、本文のほうに同様の症状が出ました。

下記のように、CSakuraEnvironment::ExpandParameter()で
コール時に毎回ではなく、言語切替時だけLoadStringするように
変更したところ、自環境では改善しました。

Index: sakura_core/env/CSakuraEnvironment.cpp
===================================================================
--- sakura_core/env/CSakuraEnvironment.cpp	(リビジョン 3706)
+++ sakura_core/env/CSakuraEnvironment.cpp	(作業コピー)
@@ -90,11 +90,22 @@
 	const CEditDoc* pcDoc = CEditDoc::GetInstance(0); //###
 
 	// Apr. 03, 2003 genta 固定文字列をまとめる
-	const wstring	PRINT_PREVIEW_ONLY		= LSW( STR_PREVIEW_ONLY );	//L"(印刷プレビューでのみ使用できます)";
+	static HINSTANCE s_hRsrc = NULL;
+	static wstring	PRINT_PREVIEW_ONLY		= L"";	//L"(印刷プレビューでのみ使用できます)";
+	static wstring	NO_TITLE				= L"";	//L"(無題)";
+	static wstring	NOT_SAVED				= L"";	//L"(保存されていません)";
+
+	// 初回と言語切替時に文字列をロードする
+	HINSTANCE hRsrc = CSelectLang::getLangRsrcInstance();
+	if( s_hRsrc != hRsrc ){
+		s_hRsrc = hRsrc;
+		PRINT_PREVIEW_ONLY		= LSW( STR_PREVIEW_ONLY );
+		NO_TITLE				= LSW( STR_NO_TITLE1 );
+		NOT_SAVED				= LSW( STR_NOT_SAVED );
+	}
+
 	const int		PRINT_PREVIEW_ONLY_LEN	= PRINT_PREVIEW_ONLY.length();
-	const wstring	NO_TITLE				= LSW( STR_NO_TITLE1 );	//L"(無題)";
 	const int		NO_TITLE_LEN			= NO_TITLE.length();
-	const wstring	NOT_SAVED				= LSW( STR_NOT_SAVED );	//L"(保存されていません)";
 	const int		NOT_SAVED_LEN			= NOT_SAVED.length();
 
 	const wchar_t *p, *r;	//	p:目的のバッファ。r:作業用のポインタ。


2014/5/11 (日) 16:44:12 novice  
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0
[2172] Re5:不具合:「開きません」のキャンセルが存在しません
▼ 神楽さん
> 「(保存されていません)」と「(印刷プレビューでのみ使用できます)」が
> Ctrl+Cする度に、交互に繰り返されます。

patchを登録しました。
http://sourceforge.net/p/sakura-editor/patchunicode/816/

2014/5/11 (日) 17:52:03 LR4  
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0
[2173] Re6:不具合:「開きません」のキャンセルが存在しません
> patchを登録しました。
> http://sourceforge.net/p/sakura-editor/patchunicode/816/


このパッチですが、直接MessageBox APIを呼び出している個所には効果が無さげです。
>>unicode:2168の冒頭で例示した[整理]ボタンで出るメッセージボックスは直に呼び出してます。

2014/5/12 (月) 17:50:31 LR4  
Mozilla/5.0 (Windows NT 6.1; rv:29.0) Gecko/20100101 Firefox/29.0
[2175] Re6:不具合:「開きません」のキャンセルが存在しません
trunk2_VMessageBoxF_fix_b.patchでMessageBox()->MYMESSAGEBOX()置換されたようですが、置換方法に問題があるようです。
MYMESSAGEBOX()の第4引数は「メッセージ文字列」ではなく「メッセージ用の書式指定文字列」であることに注意しないと。

上記パッチを適用した状態で、[名前を付けて保存]で既存ファイル(ファイル名:%s%s%s.txt)に上書きを試みたり、S_MessageBox("%s", 0)マクロを実行したりするとメッセージボックスの文字が化けるか異常終了するです(汗)。

ご確認お願いします。

2014/5/13 (火) 18:25:12 LR4  
Mozilla/5.0 (Windows NT 6.1; rv:29.0) Gecko/20100101 Firefox/29.0
[2177] Re6:不具合:「開きません」のキャンセルが存在しません
[trunk2_VMessageBoxF_fix_c.patch]
19行目: STR_BACKUP_ERR_DELETE は STR_BACKUP_ERR_MOVE の誤りではないか?
45行目: pszMsg は LS マクロで取得したポインタなのにローカルコピーしていない
→ ここまでチェックしたところで中断(他にパッチ不足とかの問題もあるかもです)。

この様子だと、労力も過多ですし将来のミス防止も難しいかな?と思いました。
次に、費用対効果が高そうな代替案パッチを貼っておきます。
採用の可否についてはお任せします。

【代替案の説明】
[MessageBoxF.h]
マクロ MessageBox は MessageBoxA/W ではなく Wrap_MessageBox に
展開するように変更

[MessageBox.cpp]
Wrap_MessageBox() は タイトル/メッセージをローカルバッファに
コピーし、明示リンクで MessageBoxA/W を呼び出す。

MessageBoxF.h は StdAfx.h に入っているので、すべての .cpp で
MessageBox が Wrap_MessageBox に展開されます。
メッセージボックス表示がすべて Wrap_MessageBox 経由になるため、
これでビルドした sakura.exe を Dependency Walker で確認すると、
USER32.dll の MessageBoxA/W への暗黙リンクは無くなっているはずです。

2014/5/13 (火) 18:26:18 LR4  
Mozilla/5.0 (Windows NT 6.1; rv:29.0) Gecko/20100101 Firefox/29.0
[2178] 代替案パッチ
【代替案パッチ】
Index: sakura_core/util/MessageBoxF.cpp
===================================================================
--- sakura_core/util/MessageBoxF.cpp	(リビジョン 3706)
+++ sakura_core/util/MessageBoxF.cpp	(作業コピー)
@@ -40,6 +40,25 @@
 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- //
 //                 メッセージボックス:実装                    //
 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- //
+int Wrap_MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
+{
+	static int (WINAPI *RealMessageBox)(HWND, LPCTSTR, LPCTSTR, UINT);
+	static HMODULE hMod = NULL;
+	if( hMod == NULL ){	// 初期化されていない場合は初期化する
+		hMod = GetModuleHandle(_T("USER32"));
+#ifdef _UNICODE
+		*(FARPROC *)&RealMessageBox = GetProcAddress(hMod, "MessageBoxW");
+#else
+		*(FARPROC *)&RealMessageBox = GetProcAddress(hMod, "MessageBoxA");
+#endif
+	}
+
+	// lpText, lpCaption をローカルバッファにコピーして MessageBox API を呼び出す
+	// ※ 使い回しのバッファが使用されていてそれが裏で書き換えられた場合でも
+	//    メッセージボックス上の Ctrl+C が文字化けしないように
+	return RealMessageBox(hWnd, std::tstring(lpText).c_str(), std::tstring(lpCaption).c_str(), uType);
+}
+
 HWND GetMessageBoxOwner(HWND hwndOwner)
 {
 	if(hwndOwner==NULL && g_pcEditWnd){
Index: sakura_core/util/MessageBoxF.h
===================================================================
--- sakura_core/util/MessageBoxF.h	(リビジョン 3706)
+++ sakura_core/util/MessageBoxF.h	(作業コピー)
@@ -37,6 +37,9 @@
 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- //
 
 //2007.10.02 kobake メッセージボックスの使用はデバッグ時に限らないので、「Debug〜」という名前を廃止
+#undef MessageBox
+#define MessageBox Wrap_MessageBox
+int Wrap_MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
 
 //テキスト整形機能付きMessageBox
 int VMessageBoxF( HWND hwndOwner, UINT uType, LPCTSTR lpCaption, LPCTSTR lpText, va_list& v );

2014/5/13 (火) 23:43:34 (--;  
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0
[2179] noviceさん
[trunk2_VMessageBoxF_fix_d.patch]

> [trunk2_VMessageBoxF_fix_c.patch]
> 19行目: STR_BACKUP_ERR_DELETE は STR_BACKUP_ERR_MOVE の誤りではないか?
> 45行目: pszMsg は LS マクロで取得したポインタなのにローカルコピーしていない

↑の *45行目* は見ておいてください

2014/5/15 (木) 12:09:16 LR4  
Mozilla/5.0 (Windows NT 6.1; rv:29.0) Gecko/20100101 Firefox/29.0
[2181] 代替案パッチ(改) 1/2
2.1.1.2では、言語を英語に切替えてもメッセージボックスのボタンが
日本語(例:はい/いいえ/キャンセル)で表示されるようです。
ついでにこの問題も同じ仕掛けで修正してみました。

投稿許可サイズをちょっとオーバーするので2回に分けます。

Index: sakura_core/CSelectLang.h
===================================================================
--- sakura_core/CSelectLang.h	(リビジョン 3706)
+++ sakura_core/CSelectLang.h	(作業コピー)
@@ -50,6 +50,7 @@
 	*/
 	static HINSTANCE getLangRsrcInstance( void );			// メッセージリソースDLLのインスタンスハンドルを返す
 	static LPCTSTR getDefaultLangString( void );			// メッセージリソースDLL未読み込み時のデフォルト言語("(Japanese)" or "(English(United States))")
+	static WORD getLangId( void ){ return m_psLangInfo? m_psLangInfo->wLangId: 0; }
 
 	static HINSTANCE InitializeLanguageEnvironment(void);		// 言語環境を初期化する
 	static HINSTANCE LoadLangRsrcLibrary( SSelLangInfo& lang );	// メッセージ用リソースDLLをロードする
Index: sakura_core/util/MessageBoxF.h
===================================================================
--- sakura_core/util/MessageBoxF.h	(リビジョン 3706)
+++ sakura_core/util/MessageBoxF.h	(作業コピー)
@@ -37,6 +37,9 @@
 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- //
 
 //2007.10.02 kobake メッセージボックスの使用はデバッグ時に限らないので、「Debug〜」という名前を廃止
+#undef MessageBox
+#define MessageBox Wrap_MessageBox
+int Wrap_MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
 
 //テキスト整形機能付きMessageBox
 int VMessageBoxF( HWND hwndOwner, UINT uType, LPCTSTR lpCaption, LPCTSTR lpText, va_list& v );

2014/5/15 (木) 12:10:26 LR4  
Mozilla/5.0 (Windows NT 6.1; rv:29.0) Gecko/20100101 Firefox/29.0
[2182] Re:代替案パッチ(改) 2/2
Index: sakura_core/util/MessageBoxF.cpp
===================================================================
--- sakura_core/util/MessageBoxF.cpp	(リビジョン 3706)
+++ sakura_core/util/MessageBoxF.cpp	(作業コピー)
@@ -40,6 +40,25 @@
 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- //
 //                 メッセージボックス:実装                    //
 // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- //
+int Wrap_MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
+{
+	static int (WINAPI *RealMessageBox)(HWND, LPCTSTR, LPCTSTR, UINT, WORD);
+	static HMODULE hMod = NULL;
+	if( hMod == NULL ){	// 初期化されていない場合は初期化する
+		hMod = GetModuleHandle(_T("USER32"));
+#ifdef _UNICODE
+		*(FARPROC *)&RealMessageBox = GetProcAddress(hMod, "MessageBoxExW");
+#else
+		*(FARPROC *)&RealMessageBox = GetProcAddress(hMod, "MessageBoxExA");
+#endif
+	}
+
+	// lpText, lpCaption をローカルバッファにコピーして MessageBox API を呼び出す
+	// ※ 使い回しのバッファが使用されていてそれが裏で書き換えられた場合でも
+	//    メッセージボックス上の Ctrl+C が文字化けしないように
+	return RealMessageBox(hWnd, std::tstring(lpText).c_str(), std::tstring(lpCaption).c_str(), uType, CSelectLang::getLangId());
+}
+
 HWND GetMessageBoxOwner(HWND hwndOwner)
 {
 	if(hwndOwner==NULL && g_pcEditWnd){

2014/6/3 (火) 23:10:15 LR4  
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0
[2189] パッチ訂正
訂正です。
Wrap_MessageBox()の最後で RealMessageBox()を呼んでる箇所を修正する必要があります。

【誤】+	return RealMessageBox(hWnd, std::tstring(lpText).c_str(), std::tstring(lpCaption).c_str(), uType, CSelectLang::getLangId());
【正】+ return RealMessageBox(hWnd, lpText? std::tstring(lpText).c_str(): NULL, lpCaption? std::tstring(lpCaption).c_str(): NULL, uType, CSelectLang::getLangId());

MessageBox API のタイトルには NULL を指定可能(デフォルトタイトル"Error"を表示)
なのに、【誤】のほうで NULL 指定すると異常終了してしまいます。

しばらく【誤】のほうを使っていたところ、
Wikiではなく、どこかから拾ってきた「選択範囲を MSDN(VS2008用) で検索」マクロで、
オンライン優先にした場合に時間がかかってエラーになるケースで異常終了しました。

2014/5/16 (金) 00:29:53 もか  
INCM1.23a
[2183] Re5:不具合:「開きません」のキャンセルが存在しません
MessageBoxやDialogBox*(ついでにSHBrowseForFolder、GetOpenFileName等)は内部でGetMessage等を呼び出してメッセージ処理をするから、
BlockingHookと同じように他のウィンドウのメッセージが処理されることを意識する必要があるってことですね
(サクラのコードはBlockingHookもほとんど他の処理が走ることを考慮していませんけど)

VMessageBoxFを表示中にさらにVMessageBoxFが表示されることがあるようです。
何かのダイアログが表示された状態で、親ウィンドウにWM_CLOSEが送られてきたとか。
ためしに、編集中ドキュメントを[X]で閉じようとして「保存しますか?」ときかれてきて、
その状態でタスクバー(Win7)から「このウィンドウを閉じる」を選んだら、
もう一つ「保存しますか?」が表示されました。
1つめが他のダイアログだった場合は、VMessageBoxFのszBufはstaticなので、
2つめをキャンセルして1つめに戻ってきた場合に、よろしくないんじゃないでしょうか。
LR4さんの代替案ならWarpでコピーされて問題なさそうです。

考慮したほうがいいことで思いつくことは
1.バッファのリサイクル(LS/LSW/to_*char)
2.staticになってる変数等の再入問題
3.API呼び出し前にチェックしたファイル・ウィンドウ・共有変数等の内容が変更になっている可能性
4.プロセス(親ウィンドウ)の終了
とかいろいろありますが現状は結構手抜きのはず。

2014/5/16 (金) 09:50:12 LR4  
Mozilla/5.0 (Windows NT 6.1; rv:29.0) Gecko/20100101 Firefox/29.0
[2186] Re6:不具合:「開きません」のキャンセルが存在しません
残念なことですが、複数のメッセージボックスを表示している場合ですが、*各メッセージボックスの文字列バッファが独立したものになっていても*、どのメッセージボックスに対するCtrl+Cも、常に最後に出したメッセージボックスのテキストがクリップボードに入ります。
最後のメッセージボックスを閉じるとひとつ前のメッセージボックスのテキストになります。
(MessageBox APIの側で常に末尾スタックに積まれたバッファポインタを参照しているのかな?という挙動です)

サクラとは別に、Visual Studioが生成する最も単純なWin32 Appに少し手を加えただけのプログラムで検証しても同様でした。

サクラでは検索ボックスと置換ボックスを同時に出して、
検索ボックス:検索条件を指定してください
置換ボックス:前方(↓) に文字列 'x' が1つも見つかりません
のメッセージを同時に出すことができます。
上記に加えて、「閉じる前に保存しますか?」も簡単に出せますね。

メッセージフックでもして自コード内にクリップボード処理を回せば矯正できるとは思いますが、さすがにそれはアレなので、複数表示についてはあきらめて期待通りには動かないのが「仕様」ということにしておくほうが賢明と思います。
1個だけ表示しているときは期待通り動く、というところまでの対策で妥協しましょう(汗)

2014/5/16 (金) 10:30:39 LR4  
Mozilla/5.0 (Windows NT 6.1; rv:29.0) Gecko/20100101 Firefox/29.0
[2187] Re7:不具合:「開きません」のキャンセルが存在しません
> 最後のメッセージボックスを閉じるとひとつ前のメッセージボックスのテキストになります。

すみません、必ずしもこのルール通りではないようです。時折、違う挙動が起きるような?…
ちなみに、メモ帳でも検索ダイアログの「"x"が見つかりません」と「無題 への変更内容を保存しますか?」を同時に出したりできますが、やはり変な挙動になります。

2014/5/16 (金) 18:21:43 LR4  
Mozilla/5.0 (Windows NT 6.1; rv:29.0) Gecko/20100101 Firefox/29.0
[2188] Re7:不具合:「開きません」のキャンセルが存在しません
>どのメッセージボックスに対するCtrl+Cも、常に最後に出したメッセージボックスのテキストがクリップボードに入ります。

Spy++で見たら、どのウィンドウがアクティブかに関わらずメッセージループを回しているメッセージボックス(最後に表示したメッセージボックス)に WM_COPY が送られていました。
エディタウィンドウをアクティブにしている時でも。

2015/7/9 (木) 22:30:13 syat  
Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.132 Safari/537.36
[2265] Re8:不具合:「開きません」のキャンセルが存在しません
LR4さんのパッチをトラッカーに登録しました。(patchunicode/816)
問題なさそうなのでこちらを採用したいと思います。

[▼次のスレッド]
INCM/CMT
Cyclamen v3.81
[ut:0.020][st:0.000]