entorno de depuración LUA (c)


QQ 282397369
mundo es un papel de copia grande, tratando de encontrar la información que desea en Internet, es tener que cargar una gran cantidad de esfuerzo.
Afortunadamente, hay una base técnica, en el caso de una demanda clara, logró alcanzar el objetivo.

Procesamiento de acceso directo

Sobre la base de los dos anteriores, entorno de depuración primero tiene que resolver es procesamiento de clave.
Pensé que esto es muy simple, descubrió por primera vez Escintila puede tratar directamente con la noticia. Entrar en un poco saber mensaje WM_NOTIFY. Está activada, esta función necesita útil en el procesamiento de las clases de mensajes de la siguiente manera:

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;
	}
}

Por supuesto, la clave es SCN_CHARADDED apoyo sólo pura, es decir, puede editar el código.
Aquí encontramos un problema: teclas TAB, las teclas de flecha no válidos

tecla TAB, una tecla de dirección

Comprobar la información que se encuentra puede manejar mensajería WM_GETDLGCODE solución

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

Cuesta más que un pequeño problema, se desarrolló sin contratiempos

F8, F9

Pero al final ha quedado atascado en el F8, F9 en estas teclas, mi intención es correr hacia el punto de interrupción F9, F8 puede solo paso operación. Con base en lo anterior, no importa cómo presionar F8, F9 no puede desencadenar cualquier caso, un poco más que intento, F1 ~ F12 son los mismos válido.
Probé en la ventana principal, puede desencadenar OnKeyUp Formulario evento, en el que se puede tratar con F1 ~ F12.
Para estudiar cómo capturar estos mensajes que tenía que empezar de mecanismo de mensajes de la VCL. Sin duda, depende del ciclo de noticias TApplication VCL en función ProcessMessage

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;

Mira analizar varias funciones, se requiere IsKeyMsg, es decir, en el que el proceso puede ser controlado

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;

Mira IsKeyMsg implementar funciones lógicas, me preocupa la información del teclado debe ir al SendMessage (END, CN_BASE + mensaje, wParam, LParam); encontrar el tipo de mensaje apropiado CN_KEYDOWN, CN_KEYUP, CN_CHAR, CN_SYSKEYDOWN, CN_SYSCHAR, por lo que hablar de noticias CN_KEYUP proceso

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;

La sensación aquí CM_CHILDKEY mensajes pueden tomar ventaja de ella. A ver si puedo capturar. Los controles en Scintilla en respuesta al tratamiento:

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

El resultado OK.
A continuación, añadir el F8, F9, en respuesta, el Bloc de notas de referencia manera ++ para lograr la totalidad de la función de plegado Alt + 1

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();
}

tratamiento MDI

Esto puede ser más implementación simplificada, utilizando PageControl de la etiqueta y comprobar la etiqueta en la que mostrar los contenidos del archivo correspondiente. El único tratamiento es recordar la ubicación se mostró la última.

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);
}

Esto no es mucho decir.
Aquí Insertar imagen Descripción

Presentación especial de contenidos variables

variable especial, se refiere a la estructura de la imagen y el texto XML

imagen

El procesamiento de imágenes por MAT, a salido directamente sobre el lienzo.

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);
	}
}

Aquí Insertar imagen Descripción

texto estructurado XML

De hecho, XML y LUA son texto, el uso directo de Scintilla expresa no podría ser mejor. MDI sobre la base de lo anterior, se abre directamente un nuevo botón "ventana de depuración".
Aquí Insertar imagen Descripción

identificador de ventana

Esta en la palabra, si quieren ver el efecto, directamente a la manija de la ventana frente interno.

recuperación inicial, el entorno de depuración LUA ha alcanzado básicamente los objetivos esperados. Y otra posterior re-optimización para mejorar gradualmente en el curso.

Liberadas nueve artículos originales · ganado elogios 2 · Vistas 546

Supongo que te gusta

Origin blog.csdn.net/drgraph/article/details/104507323
Recomendado
Clasificación