LUAのデバッグ環境(C)


QQ 282397369
世界は大きなコピー用紙では、インターネット上で必要な情報を見つけようと、それは多くの労力を充電する必要があります。
幸いなことに、技術的な根拠があり、明確な需要の場合には、目標を達成するために管理。

ショートカット処理

前の2に基づいて、解決するための環境最初の必要性をデバッグすることは重要な処理です。
私は最初のScintillaのニュースを直接扱うことができます発見し、これは非常に単純であると思いました。ニュースの少しを知って少し深くWM_NOTIFY探ります。チェック、この関数は次のようにメッセージクラスを処理する際に有用必要があります。

void __fastcall TCbwSynEditor::OnEditorMsg(Messages::TMessage & message) {
	if(GetTickCount() - FCreateMoment < 1000)
		return;
	SCNotification *pSCNotification = (SCNotification*)(message.LParam);
	if(pSCNotification->nmhdr.idFrom != SCINT_ID)
		return;
	int iValue;
	switch(pSCNotification->nmhdr.code) {
	case SCN_DOUBLECLICK:
		if(OnEditor_DblClick)
			OnEditor_DblClick(this);
		break;
	case SCN_UPDATEUI:
		if(OnEditor_Click)
			OnEditor_Click(this);
		if(FPaintBox_Assert)
			FPaintBox_Assert->Repaint();
		if(PageControl && PageControl->ActivePage)
			PageControl->ActivePage->Tag = GetCurrentLine();
		break;
	case SCI_SETMARGINSENSITIVEN:
		SendEditor(SCI_TOGGLEFOLD, CurrentLine, 0);
		break;
	case SCN_SAVEPOINTREACHED:   		// SCI_SETSAVEPOINT消息将会触发SCN_SAVEPOINTREACHED事件通知
//		THelper::Debug::AddLog(L"Saved...", clBlue, true);
		FileModified = false;
		break;
	case SCN_SAVEPOINTLEFT: 			// 当文档状态变为modified时,将会触发SCN_SAVEPOINTLEFT事件通知
//		THelper::Debug::AddLog(L"Changed...", clBlue, true);
		FileModified = true;
		break;
	case SCN_MARGINCLICK:
		iValue = SendEditor(SCI_LINEFROMPOSITION, pSCNotification->position);		// 点击位置行号
		if(pSCNotification->margin == 1) {
			SendEditor(SCI_TOGGLEFOLD, iValue);
			Application->ProcessMessages();
			FPaintBox_Assert->Invalidate();
		}
		break;
	case SCN_CHARADDED:
		THelper::Debug::AddLog(THelper::FormatString(L"%d", pSCNotification->ch), clBlue, true);
		break;
	case SCN_KEY:
	case SC_KEYMENU:
		THelper::Debug::AddLog(THelper::FormatString(L"%d", pSCNotification->ch), clBlue, true);
		break;
	default:
		break;
	}
}

もちろん、キーを使用すると、コードを編集することができ、あること、ただ純粋な支援SCN_CHARADDEDです。
ここでは、問題を発見:TABキー、矢印キーを無効

Tabキー、方向キー

ソリューションWM_GETDLGCODEメッセージング処理することができた情報を確認してください

void __fastcall TCbwSynEditor::OnDlgCode(Messages::TMessage & message) {
	message.Result = DLGC_WANTALLKEYS | DLGC_WANTARROWS | DLGC_WANTTAB;  // 接受方向键和TAB键
}

それは少し問題よりも多くの費用がかかる、スムーズに行ってきました

F8、F9

しかし、最終的にはF8で立ち往生、F9は、これらのキーの上に、私の意図は、ブレークポイントのF9に実行することで、F8は、シングルステップすることができます操作。以上を踏まえ、F8キーを押し、F9はもう少し試しよりも、任意のイベントをトリガすることはできませんどんなには、F1〜F12は同じ無効です。
私はあなたがF1〜F12を扱うことが可能なイベントのフォームを、OnKeyUpをトリガすることができ、メインウィンドウでテスト。
それはVCLのメッセージメカニズムからスタートしなければならなかった、これらのメッセージをキャプチャする方法を研究するために。それは確かにProcessMessage関数の中でニュースサイクルVCLのTApplicationに依存します

function TApplication.ProcessMessage(var Msg: TMsg): Boolean;
var
  Handled: Boolean;
begin
  Result := False;
  if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
  begin
    Result := True;
    if Msg.Message <> WM_QUIT then
    begin
      Handled := False;
      if Assigned(FOnMessage) then
        FOnMessage(Msg, Handled);
      if not IsHintMsg(Msg) and not Handled and not IsMDIMsg(Msg) and
        not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then
      begin
        TranslateMessage(Msg);
        DispatchMessage(Msg);
      end;
    end
    else
      FTerminate := True;
  end;
end;

いくつかの機能を分析見える、IsKeyMsgは、プロセスを制御することができ、すなわち、ここで、必要とされます

function TApplication.IsKeyMsg(var Msg: TMsg): Boolean;
var
  Wnd: HWND;
begin
  Result := False;
  with Msg do
    if (Message >= WM_KEYFIRST) and (Message <= WM_KEYLAST) then
    begin
      Wnd := GetCapture;
      if Wnd = 0 then
      begin
        Wnd := HWND;
        if (MainForm <> nil) and (Wnd = MainForm.ClientHandle) then
          Wnd := MainForm.Handle
        else
        begin
          // Find the nearest VCL component. Non-VCL windows wont know what
          // to do with CN_BASE offset messages anyway.
          // TOleControl.WndProc needs this for TranslateAccelerator
          while (FindControl(Wnd) = nil) and (Wnd <> 0) do
            Wnd := GetParent(Wnd);
          if Wnd = 0 then
            Wnd := HWND;
        end;
        if SendMessage(Wnd, CN_BASE + Message, WParam, LParam) <> 0 then
          Result := True;
      end
      else if (LongWord(GetWindowLong(Wnd, GWL_HINSTANCE)) = HInstance) then
      begin
        if SendMessage(Wnd, CN_BASE + Message, WParam, LParam) <> 0 then
          Result := True;
      end;
    end;
end;

IsKeyMsgは、論理機能を実装見て、私は午前のSendMessage(WND、CN_BASE +メッセージ、WPARAM、LPARAM)に行くべき関係するキーボード情報、適切なメッセージ・タイプCN_KEYDOWN、CN_KEYUP、CN_CHAR、CN_SYSKEYDOWN、CN_SYSCHARを見つけ、そのCN_KEYUPニュースについての話プロセス

procedure TWinControl.CNKeyDown(var Message: TWMKeyDown);
var
  Mask: Integer;
begin
  with Message do
  begin
    Result := 1;
    UpdateUIState(Message.CharCode);
    if IsMenuKey(Message) then
      Exit;
    if not(csDesigning in ComponentState) then
    begin
      if Perform(CM_CHILDKEY, CharCode, Integer(Self)) <> 0 then
        Exit;
      Mask := 0;
      case CharCode of
        VK_TAB:
          Mask := DLGC_WANTTAB;
        VK_LEFT, VK_RIGHT, VK_UP, VK_DOWN:
          Mask := DLGC_WANTARROWS;
        VK_RETURN, VK_EXECUTE, VK_ESCAPE, VK_CANCEL:
          Mask := DLGC_WANTALLKEYS;
      end;
      if (Mask <> 0) and (Perform(CM_WANTSPECIALKEY, CharCode, 0) = 0) and
        (Perform(WM_GETDLGCODE, 0, 0) and Mask = 0) and
        (GetParentForm(Self).Perform(CM_DIALOGKEY, CharCode, KeyData) <> 0) then
        Exit;
    end;
    Result := 0;
  end;
end;

ここで感じCM_CHILDKEYメッセージは、それを活用することができます。私はキャプチャすることができます参照してください。治療に応答したScintillaのコントロールには:

void __fastcall TCbwSynEditor::OnChildKey(Messages::TMessage & message) {
	WORD Key = message.WParam;
}

結果OK。
その後、反応して、折りたたみ機能はAlt + 1のすべてを達成するための参照メモ帳++の道をF8、F9を追加

void __fastcall TCbwSynEditor::OnChildKey(Messages::TMessage & message) {
	WORD Key = message.WParam;
	if( (Key == 120 || Key == 119) && FOnSpecialKey)
		FOnSpecialKey(message);
	if(Key == 49 && (GetKeyState(VK_MENU) < 0))  	// alt + 1: 全部折叠
		FoldAll();
}

MDI治療

これは、最も対応するファイルの内容を表示するには上のラベルを確認し、ラベルとしてPageControlを使用して、実装を簡素化することができます。唯一の治療は、場所が最後に表示されていた覚えておくことです。

void __fastcall TCbwSynEditor::OnCloseFile(TObject *Sender, int ATabIndex, bool &ACanClose) {
	UnicodeString fileName = PageControl->Pages[ATabIndex]->Caption.Trim();
	for(int i = 0; i < FFileNames->Count; ++i) {
		UnicodeString fn = FFileNames->Strings[i];
		if(THelper::File::ExtractPureFileName(fn) == fileName) {
			FFileNames->Delete(i);
			Clear();
			i = CAST_RANGE(i, 0, FFileNames->Count - 1);
			if(FFileNames->Count)
				LoadFromFile(FFileNames->Strings[i]);
			break;
		}
	}
}

void __fastcall TCbwSynEditor::OnSelectFile(TObject* Sender) {
	CBW_PREVENT_CHANGE_LOOP;
	int index = PageControl->ActivePageIndex;
	if(index == -1)
		return;
	UnicodeString fileName = PageControl->ActivePage->Hint;
	LoadFromFile(fileName, true);
}

これは言っても過言ではありません。
ここに画像を挿入説明

特殊変数コンテンツ提示

特殊変数は、画像とテキストのXML構造を指します

画像

キャンバス上にまっすぐに直接MATによる画像処理、。

void __fastcall TCbwSynEditor::OnPaintBox_Debug(TObject* Sender) {
	TCanvas * canvas = FPaintBox_Debug->Canvas;
	THelper::Graphics::FillCanvas(canvas, TColor(0xFFEFEF), TColor(0xFFEFEF));
	canvas->Rectangle(0, 0, FPaintBox_Debug->Width, FPaintBox_Debug->Height);

	if(FPaintBox_Debug->Hint == L"MAT") {
		CBW_CAST(TDrMat, drMat, FPaintBox_Debug->Tag);
		cv::Mat mat = drMat->mat;
		if(mat.empty())
			return;
		double height = std::min(mat.rows, FPaintBox_Debug->Height);
		double ratio = height / mat.rows;
		CvHelper::DrawToCanvas(canvas, drMat->mat, TRect(0, 0, mat.cols * ratio, mat.rows * ratio), DRGRAPH_FLAG_FLIP_Y);
	}
}

ここに画像を挿入説明

XML構造化テキスト

実際には、XMLおよびLUAは、Scintillaのを直接使用することは良いことができませんでしたテキスト表現されています。MDIは、上記に基づいて、直接新しい「デバッグウィンドウ」ボタンを開きます。
ここに画像を挿入説明

ウィンドウハンドル

この言葉に、効果を確認したい場合は、直接ホームフロントウィンドウハンドルへ。

最初のリコールは、LUAデバッグ環境は基本的に期待される目標に達しています。そして、他のその後の再最適化はもちろんで徐々に改善します。

リリース9件のオリジナルの記事 ウォンの賞賛2 ビュー546

おすすめ

転載: blog.csdn.net/drgraph/article/details/104507323