質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MFC

MFC (Microsoft Fouondation Class)とは、MicrosoftがVC++用に開発したWindows用アプリケーションのフレームワークです。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

3677閲覧

MFCでCRichEditCtrlのCtrl+Cだけ効かない

kamekawashinta

総合スコア39

MFC

MFC (Microsoft Fouondation Class)とは、MicrosoftがVC++用に開発したWindows用アプリケーションのフレームワークです。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/01/29 09:55

編集2019/01/29 10:33

VS2015を使い、GUIアプリケーションを作成しています。

CMainFrameのメンバがCDockablePaneの派生クラス DockPane
DockPaneのメンバがCRichEditCtrlの派生クラス RichCtrl
です。

作成されたCRichEditCtrl内で
Ctrl +A(全選択)、Ctrl +X(切り取り)、Ctrl +Z(アンドゥ)、等は効くのですが

文字選択した後Ctrl +C だけ効かないのが現象となっています。
ちなみにポップアップメニューのコピーは有効でした。

なぜこのようになるのか見当がつきません。
CEditを使った場合はうまくいくようです。
CRichEditCtrl内でCtrl+Cを有効化する方法をご教示願いたく思います。

RichCtrlの実装抜粋すると

C++

1BEGIN_MESSAGE_MAP(RichCtrl, CRichEditCtrl) 2 3 ON_WM_CONTEXTMENU() 4 ON_COMMAND(ID_EDIT_COPY, OnPopupCopy) 5 ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdatePopupCopy) 6 ON_COMMAND(ID_EDIT_CUT, OnPopupCut) 7 ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdatePopupCopy) 8 ON_COMMAND(ID_EDIT_PASTE, OnPopupPaste) 9 ON_COMMAND(ID_EDIT_CLEAR_ALL, OnPopupCleartext) 10 ON_UPDATE_COMMAND_UI(ID_EDIT_CLEAR_ALL, OnUpdatePopupCleartext) 11 ON_COMMAND(ID_EDIT_SELECT_ALL, OnPopupStatusSelectall) 12 ON_UPDATE_COMMAND_UI(ID_EDIT_SELECT_ALL, OnUpdatePopupCleartext) 13 ON_COMMAND(ID_EDIT_UNDO, OnPopupUndo) 14 ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdatePopupUndo) 15 16END_MESSAGE_MAP() 17 18void RichCtrl::OnContextMenu(CWnd* pWnd, CPoint point) 19{ 20 CMenu menu; 21 if (menu.LoadMenu(IDR_REPOPUP)) 22 { 23 CMenu* pPopup = menu.GetSubMenu(0); 24 ASSERT(pPopup != NULL); 25 pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, 26 point.x, point.y, this); 27 } 28} 29void RichCtrl::OnPopupCopy() 30{ 31 SendMessage(WM_COPY, 0, 0); 32} 33 34void RichCtrl::OnUpdatePopupCopy(CCmdUI* pCmdUI) 35{ 36 SendMessage(EM_EXGETSEL, 0, (LPARAM)&m_crStatus); 37 pCmdUI->Enable(m_crStatus.cpMin != m_crStatus.cpMax); 38} 39void RichCtrl::OnPopupCut() 40{ 41 SendMessage(WM_CUT, 0, 0); 42} 43 44void RichCtrl::OnPopupUndo() 45{ 46 SendMessage(WM_UNDO, 0, 0); 47} 48 49void RichCtrl::OnUpdatePopupUndo(CCmdUI* pCmdUI) 50{ 51 pCmdUI->Enable((SendMessage(EM_CANUNDO, 0, 0)) != 0); 52} 53 54void RichCtrl::OnPopupPaste() 55{ 56 SendMessage(WM_PASTE, 0, 0); 57} 58 59void RichCtrl::OnPopupStatusSelectall() 60{ 61 m_crStatus.cpMin = 0; 62 m_crStatus.cpMax = -1; 63 SendMessage(EM_EXSETSEL, 0, (LPARAM)&m_crStatus); 64} 65 66void RichCtrl::OnUpdatePopupCleartext(CCmdUI* pCmdUI) 67{ 68 pCmdUI->Enable(SendMessage(WM_GETTEXTLENGTH, NULL, NULL) != 0); 69} 70 71void RichCtrl::OnPopupCleartext() 72{ 73 OnPopupStatusSelectall(); 74 SendMessage(WM_CLEAR, 0, 0); 75}

のようになっています。

よろしくお願いいたします。

追記

//アプリ名.rcファイル "C", ID_EDIT_COPY, VIRTKEY, CONTROL, NOINVERT

をコメントアウトした場合、CRichEditCtrlのCtrl+Cは効きましたが
同じ画面上の別のCScrollViewからの派生クラスでのCtrl+Cが効かなくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

アクセラレータキーのリソースに追加されていると、
Ctrl+CはID_EDIT_COPYコマンドに変換されてしまっていると思いますので、
そのコマンドを捕まえて処理する必要があります。

試していませんが、
CDockablePaneの派生クラスの方で
ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
などとイベントハンドラを作成して、Ctrl+CでOnEditCopyが呼ばれますか?

であれば、その中でリッチコントロールのコピーを実行すれば良いかと思います。


別案追記:

上記案が駄目な場合、こちらもうまく動くかは判りませんが、

例えば
CScrollViewからの派生クラス側の
OnUpdateEditCopy冒頭で

cpp

1if (リッチエディットコントロールにフォーカスがある場合) { 2 pCmdUI->Enable(TRUE); 3 return; 4}

OnEditCopy冒頭で

cpp

1if (リッチエディットコントロールにフォーカスがある場合) { 2 リッチコントロールのコピーを実行するコード 3 return; 4}

などと書くという方法もあります。
ちょっと美しくないかもしれませんが、周りに聞いた感じではこんな対策を採っている人がいましたので参考になれば幸いです。

投稿2019/01/30 00:17

編集2019/01/30 02:10
takabosoft

総合スコア8356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kamekawashinta

2019/01/30 01:18

CDockablePaneの派生クラスの方に ON_COMMAND(ID_EDIT_COPY, OnEditCopy) と void DockPane::OnEditCopy() { SendMessage(WM_COPY, 0, 0); } を追加しEdit内でCtrl +CしましたがOnEditCopy()は呼ばれませんでした また、アクセラレータキーのリソースには "A", ID_EDIT_SELECT_ALL, VIRTKEY, CONTROL, NOINVERT もあるのですが、Edit内でCtrl +Aは効くところがよくわからない点です。
takabosoft

2019/01/30 01:44

SendMessage(WM_COPY, 0, 0)の行にブレークポイントを貼ってリッチコントロールにフォーカスが在る状態でCtrl+Cしてもブレークしませんか? (その条件でも、CScrollViewの派生クラスのイベントハンドラの方に行っちゃいますかね?) Ctrl+Aなど他が効くのは、何か別の対策が講じられているのかなという気がしないでもないのですが、 ソースが無いのでこちらでは確認できないんですよね・・・。
takabosoft

2019/01/30 02:00 編集

ちなみに、ブレークしなかったら何の意味も無いですが、書き方としては以下のほうがよいです。 void DockPane::OnEditCopy() { RichCtrl.Copy(); } SendMessage(WM_COPY, 0, 0);は自分自身(DockPane)にWM_COPYを送信しているので、リッチコントロールに届いていないです。
takabosoft

2019/01/30 02:12

void DockPane::OnEditCopy()でブレークしなかった場合の別案も提示しました。 この別案はリッチコントロールにフォーカスがある状態でCtrl+Cをしても、CScrollViewからの派生クラスのOnUpdateEditCopyやOnEditCopyが呼ばれる事が前提の修正案です。
kamekawashinta

2019/01/30 02:41

>SendMessage(WM_COPY, 0, 0)の行にブレークポイントを貼ってリッチコントロールにフォーカスが在る状態でCtrl+Cしてもブレークしませんか? ブレークしないですね……CScrollViewの派生クラスのイベントハンドラの方にも行かず。何か他のソースで引っかかっているかもしれません。調査します。 ちなみに、CDockablePaneの派生クラス以前は CControlBarから派生されており、そのCControlBarは、CEditを保持していました。 現在はCDockablePaneの派生クラスがRichEditCtrlの派生クラスを持っているという状況です。 内部処理はほぼ変えていません(呼び出す関数等は変更なし) 派生元のクラスを変更したことでショートカットキーの不具合が出る理由が不明となっています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問