И почему тогда этот пример только подтверждает изложенную мной "бредовую" концепцию? Зачем ты его привел?
Еще одно подтверждение бредовых концепций. Потому что вся ide буквально обертка на созданный другими компонент. Как тракторист, сидящий в тракторе.
Как сильно понизились ставки. То, что в одно лицо хотя бы выбор шрифта в программе можно реализовать - истина. Ты это только что убедительно доказал.
Можно и самому написать если руки не из задницы. Код (Pascal): program SimpleEditor; uses Windows, Messages, SysUtils; const MAX_LINES = 10000; MAX_COLS = 1000; CHAR_WIDTH = 8; CHAR_HEIGHT = 16; LINE_SPACING = 20; LEFT_MARGIN = 50; TOP_MARGIN = 10; SCROLLBAR_WIDTH = 20; LINE_NUMBER_WIDTH = 40; CURRENT_LINE_COLOR = $E8E8E8; type TCell = record Ch: Char; Attr: Byte; end; TEditorModel = record Cells: array[0..MAX_LINES - 1, 0..MAX_COLS - 1] of TCell; LineCount: Integer; CurLine, CurCol: Integer; end; TEditorView = record Handle: HWND; VScroll, HScroll: HWND; ScrollLine, ScrollCol: Integer; MaxScrollLine, MaxScrollCol: Integer; Width, Height: Integer; end; var Model: TEditorModel; View: TEditorView; Msg: TMsg; // ==================== ВСПОМОГАТЕЛЬНЫЕ ==================== function GetLineLen(Line: Integer): Integer; begin Result := 0; while (Result < MAX_COLS) and (Model.Cells[Line, Result].Ch <> #0) do Inc(Result); end; function GetVisibleLines: Integer; var ClientRect: TRect; begin GetClientRect(View.Handle, ClientRect); Result := (ClientRect.Bottom - ClientRect.Top - TOP_MARGIN) div LINE_SPACING; if Result < 1 then Result := 1; end; function GetVisibleCols: Integer; var ClientRect: TRect; begin GetClientRect(View.Handle, ClientRect); Result := (ClientRect.Right - ClientRect.Left - LEFT_MARGIN - SCROLLBAR_WIDTH) div CHAR_WIDTH; if Result < 1 then Result := 1; end; procedure UpdateScrollRanges; var i, MaxLineLen: Integer; VisibleLines, VisibleCols: Integer; si: TScrollInfo; begin VisibleLines := GetVisibleLines; VisibleCols := GetVisibleCols; MaxLineLen := 0; for i := 0 to Model.LineCount - 1 do begin if GetLineLen(i) > MaxLineLen then MaxLineLen := GetLineLen(i); end; if Model.LineCount > VisibleLines then View.MaxScrollLine := Model.LineCount - VisibleLines else View.MaxScrollLine := 0; if View.ScrollLine > View.MaxScrollLine then View.ScrollLine := View.MaxScrollLine; if View.ScrollLine < 0 then View.ScrollLine := 0; si.cbSize := SizeOf(si); si.fMask := SIF_RANGE or SIF_PAGE or SIF_POS; si.nMin := 0; si.nMax := Model.LineCount - 1; si.nPage := VisibleLines; si.nPos := View.ScrollLine; SetScrollInfo(View.VScroll, SB_CTL, si, True); if MaxLineLen > VisibleCols then View.MaxScrollCol := MaxLineLen - VisibleCols else View.MaxScrollCol := 0; if View.ScrollCol > View.MaxScrollCol then View.ScrollCol := View.MaxScrollCol; if View.ScrollCol < 0 then View.ScrollCol := 0; si.fMask := SIF_RANGE or SIF_PAGE or SIF_POS; si.nMin := 0; si.nMax := MaxLineLen; si.nPage := VisibleCols; si.nPos := View.ScrollCol; SetScrollInfo(View.HScroll, SB_CTL, si, True); end; procedure UpdateCaret; begin SetCaretPos(LEFT_MARGIN + (Model.CurCol - View.ScrollCol) * CHAR_WIDTH, TOP_MARGIN + (Model.CurLine - View.ScrollLine) * LINE_SPACING); end; procedure UpdateWindowTitle; var Title: string; begin Title := Format('Editor - Line: %d, Col: %d', [Model.CurLine + 1, Model.CurCol + 1]); SetWindowText(View.Handle, PChar(Title)); end; procedure ScrollToCursor; var VisibleLines, VisibleCols: Integer; begin VisibleLines := GetVisibleLines; VisibleCols := GetVisibleCols; if Model.CurLine < View.ScrollLine then View.ScrollLine := Model.CurLine else if Model.CurLine >= View.ScrollLine + VisibleLines then View.ScrollLine := Model.CurLine - VisibleLines + 1; if Model.CurCol < View.ScrollCol then View.ScrollCol := Model.CurCol else if Model.CurCol >= View.ScrollCol + VisibleCols then View.ScrollCol := Model.CurCol - VisibleCols + 1; UpdateScrollRanges; InvalidateRect(View.Handle, nil, True); UpdateWindowTitle; end; // ==================== ОПЕРАЦИИ ==================== procedure InsertChar(ch: Char); var i, Len: Integer; begin Len := GetLineLen(Model.CurLine); if Len >= MAX_COLS - 1 then Exit; for i := Len downto Model.CurCol + 1 do Model.Cells[Model.CurLine, i] := Model.Cells[Model.CurLine, i - 1]; Model.Cells[Model.CurLine, Model.CurCol].Ch := ch; Inc(Model.CurCol); ScrollToCursor; UpdateCaret; InvalidateRect(View.Handle, nil, True); end; procedure NewLine; var i, j: Integer; Len: Integer; begin if Model.LineCount >= MAX_LINES then Exit; Len := GetLineLen(Model.CurLine); for i := Model.LineCount downto Model.CurLine + 2 do begin for j := 0 to MAX_COLS - 1 do Model.Cells[i, j] := Model.Cells[i - 1, j]; end; for j := Model.CurCol to Len - 1 do Model.Cells[Model.CurLine + 1, j - Model.CurCol] := Model.Cells[Model.CurLine, j]; for j := Model.CurCol to Len - 1 do Model.Cells[Model.CurLine, j].Ch := #0; Inc(Model.LineCount); Inc(Model.CurLine); Model.CurCol := 0; ScrollToCursor; UpdateCaret; InvalidateRect(View.Handle, nil, True); end; procedure DeleteChar; var i, j, Len: Integer; begin if Model.CurCol > 0 then begin Len := GetLineLen(Model.CurLine); for i := Model.CurCol to Len - 1 do Model.Cells[Model.CurLine, i - 1] := Model.Cells[Model.CurLine, i]; Dec(Model.CurCol); Model.Cells[Model.CurLine, Len - 1].Ch := #0; InvalidateRect(View.Handle, nil, True); end else if Model.CurLine > 0 then begin Model.CurCol := GetLineLen(Model.CurLine - 1); for i := 0 to GetLineLen(Model.CurLine) - 1 do Model.Cells[Model.CurLine - 1, Model.CurCol + i] := Model.Cells[Model.CurLine, i]; for i := Model.CurLine to Model.LineCount - 2 do begin for j := 0 to MAX_COLS - 1 do Model.Cells[i, j] := Model.Cells[i + 1, j]; end; Dec(Model.LineCount); for i := 0 to MAX_COLS - 1 do Model.Cells[Model.LineCount, i].Ch := #0; Dec(Model.CurLine); ScrollToCursor; InvalidateRect(View.Handle, nil, True); end; UpdateCaret; end; procedure DeleteCharRight; var i, j, Len: Integer; begin if Model.CurCol < GetLineLen(Model.CurLine) then begin Len := GetLineLen(Model.CurLine); for i := Model.CurCol + 1 to Len - 1 do Model.Cells[Model.CurLine, i - 1] := Model.Cells[Model.CurLine, i]; Model.Cells[Model.CurLine, Len - 1].Ch := #0; InvalidateRect(View.Handle, nil, True); end else if Model.CurLine + 1 < Model.LineCount then begin Len := GetLineLen(Model.CurLine); for i := 0 to GetLineLen(Model.CurLine + 1) - 1 do Model.Cells[Model.CurLine, Len + i] := Model.Cells[Model.CurLine + 1, i]; for i := Model.CurLine + 1 to Model.LineCount - 2 do begin for j := 0 to MAX_COLS - 1 do Model.Cells[i, j] := Model.Cells[i + 1, j]; end; Dec(Model.LineCount); for i := 0 to MAX_COLS - 1 do Model.Cells[Model.LineCount, i].Ch := #0; InvalidateRect(View.Handle, nil, True); end; UpdateCaret; end; procedure InsertTab; var i: Integer; begin for i := 1 to 4 do InsertChar(' '); end; procedure MoveCursor(Line, Col: Integer); begin if Line < 0 then Line := 0; if Line >= Model.LineCount then Line := Model.LineCount - 1; if Col < 0 then Col := 0; if Col > GetLineLen(Line) then Col := GetLineLen(Line); Model.CurLine := Line; Model.CurCol := Col; ScrollToCursor; UpdateCaret; UpdateWindowTitle; end; // ==================== ОТРИСОВКА ==================== procedure HighlightCurrentLine(dc: HDC); var Rect: TRect; CurrentLineVisible: Integer; begin if (Model.CurLine < View.ScrollLine) or (Model.CurLine >= View.ScrollLine + GetVisibleLines) then Exit; CurrentLineVisible := Model.CurLine - View.ScrollLine; Rect.Left := 0; Rect.Top := TOP_MARGIN + CurrentLineVisible * LINE_SPACING; Rect.Right := View.Width - SCROLLBAR_WIDTH; Rect.Bottom := Rect.Top + CHAR_HEIGHT; SetBkColor(dc, CURRENT_LINE_COLOR); ExtTextOut(dc, 0, 0, ETO_OPAQUE, @Rect, nil, 0, nil); end; procedure DrawLineNumbers(dc: HDC); var i, Y: Integer; StartLine, EndLine: Integer; VisibleLines: Integer; NumberStr: string; OldBkMode: Integer; OldTextColor: COLORREF; begin VisibleLines := GetVisibleLines; StartLine := View.ScrollLine; EndLine := StartLine + VisibleLines; if EndLine > Model.LineCount then EndLine := Model.LineCount; OldBkMode := SetBkMode(dc, TRANSPARENT); OldTextColor := SetTextColor(dc, RGB(100, 100, 100)); Y := TOP_MARGIN; for i := StartLine to EndLine - 1 do begin NumberStr := IntToStr(i + 1); TextOut(dc, LEFT_MARGIN - LINE_NUMBER_WIDTH + 5, Y, PChar(NumberStr), Length(NumberStr)); Y := Y + LINE_SPACING; end; SetBkMode(dc, OldBkMode); SetTextColor(dc, OldTextColor); end; procedure DrawText(dc: HDC); var i, j, X, Y: Integer; StartLine, EndLine: Integer; VisibleCols: Integer; begin StartLine := View.ScrollLine; EndLine := StartLine + GetVisibleLines; if EndLine > Model.LineCount then EndLine := Model.LineCount; VisibleCols := GetVisibleCols; Y := TOP_MARGIN; for i := StartLine to EndLine - 1 do begin X := LEFT_MARGIN; for j := View.ScrollCol to View.ScrollCol + VisibleCols - 1 do begin if Model.Cells[i, j].Ch <> #0 then begin SetTextColor(dc, RGB(0, 0, 0)); SetBkColor(dc, RGB(255, 255, 255)); TextOut(dc, X, Y, @Model.Cells[i, j].Ch, 1); end; Inc(X, CHAR_WIDTH); end; Inc(Y, LINE_SPACING); end; end; procedure DrawAll(dc: HDC); begin HighlightCurrentLine(dc); DrawLineNumbers(dc); DrawText(dc); end; // ==================== ОБРАБОТЧИКИ ==================== procedure OnPaint; var ps: TPaintStruct; dc: HDC; Font: HFONT; OldFont: HFONT; begin dc := BeginPaint(View.Handle, ps); Font := CreateFont(CHAR_HEIGHT, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FIXED_PITCH or FF_MODERN, 'Courier New'); OldFont := SelectObject(dc, Font); DrawAll(dc); SelectObject(dc, OldFont); DeleteObject(Font); EndPaint(View.Handle, ps); end; procedure OnVScroll(wParam: WPARAM); var si: TScrollInfo; NewPos: Integer; begin si.cbSize := SizeOf(si); si.fMask := SIF_ALL; GetScrollInfo(View.VScroll, SB_CTL, si); case LoWord(wParam) of SB_LINEUP: NewPos := View.ScrollLine - 1; SB_LINEDOWN: NewPos := View.ScrollLine + 1; SB_PAGEUP: NewPos := View.ScrollLine - GetVisibleLines; SB_PAGEDOWN: NewPos := View.ScrollLine + GetVisibleLines; SB_THUMBTRACK: NewPos := si.nTrackPos; else Exit; end; if NewPos < 0 then NewPos := 0; if NewPos > View.MaxScrollLine then NewPos := View.MaxScrollLine; if NewPos <> View.ScrollLine then begin View.ScrollLine := NewPos; UpdateScrollRanges; InvalidateRect(View.Handle, nil, True); UpdateCaret; end; end; procedure OnHScroll(wParam: WPARAM); var si: TScrollInfo; NewPos: Integer; begin si.cbSize := SizeOf(si); si.fMask := SIF_ALL; GetScrollInfo(View.HScroll, SB_CTL, si); case LoWord(wParam) of SB_LINELEFT: NewPos := View.ScrollCol - 1; SB_LINERIGHT: NewPos := View.ScrollCol + 1; SB_PAGELEFT: NewPos := View.ScrollCol - GetVisibleCols; SB_PAGERIGHT: NewPos := View.ScrollCol + GetVisibleCols; SB_THUMBTRACK: NewPos := si.nTrackPos; else Exit; end; if NewPos < 0 then NewPos := 0; if NewPos > View.MaxScrollCol then NewPos := View.MaxScrollCol; if NewPos <> View.ScrollCol then begin View.ScrollCol := NewPos; UpdateScrollRanges; InvalidateRect(View.Handle, nil, True); UpdateCaret; end; end; procedure OnMouseDown(X, Y: Integer); var ClickedLine, ClickedCol: Integer; begin SetFocus(View.Handle); if X < LEFT_MARGIN - LINE_NUMBER_WIDTH then begin ClickedLine := View.ScrollLine + (Y - TOP_MARGIN) div LINE_SPACING; if ClickedLine < 0 then ClickedLine := 0; if ClickedLine >= Model.LineCount then ClickedLine := Model.LineCount - 1; MoveCursor(ClickedLine, 0); Exit; end; ClickedLine := View.ScrollLine + (Y - TOP_MARGIN) div LINE_SPACING; if ClickedLine < 0 then ClickedLine := 0; if ClickedLine >= Model.LineCount then ClickedLine := Model.LineCount - 1; ClickedCol := View.ScrollCol + (X - LEFT_MARGIN) div CHAR_WIDTH; if ClickedCol < 0 then ClickedCol := 0; MoveCursor(ClickedLine, ClickedCol); end; procedure OnChar(wParam: WPARAM); begin case wParam of 8: DeleteChar; 13: NewLine; 9: InsertTab; else if wParam >= 32 then InsertChar(Char(wParam)); end; UpdateCaret; end; procedure OnKeyDown(wParam: WPARAM); begin case wParam of VK_LEFT: MoveCursor(Model.CurLine, Model.CurCol - 1); VK_RIGHT: MoveCursor(Model.CurLine, Model.CurCol + 1); VK_UP: MoveCursor(Model.CurLine - 1, Model.CurCol); VK_DOWN: MoveCursor(Model.CurLine + 1, Model.CurCol); VK_HOME: MoveCursor(Model.CurLine, 0); VK_END: MoveCursor(Model.CurLine, GetLineLen(Model.CurLine)); VK_DELETE: DeleteCharRight; end; UpdateCaret; end; // ==================== ОКОННАЯ ПРОЦЕДУРА ==================== function WndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall; var i, j: Integer; begin Result := 0; case Msg of WM_CREATE: begin View.Handle := hWnd; Model.LineCount := 1; for i := 0 to MAX_LINES - 1 do for j := 0 to MAX_COLS - 1 do Model.Cells[i, j].Ch := #0; Model.CurLine := 0; Model.CurCol := 0; View.ScrollLine := 0; View.ScrollCol := 0; View.VScroll := CreateWindow('SCROLLBAR', nil, WS_CHILD or WS_VISIBLE or SBS_VERT, 0, 0, SCROLLBAR_WIDTH, 0, hWnd, 0, HInstance, nil); View.HScroll := CreateWindow('SCROLLBAR', nil, WS_CHILD or WS_VISIBLE or SBS_HORZ, 0, 0, 0, SCROLLBAR_WIDTH, hWnd, 0, HInstance, nil); UpdateScrollRanges; UpdateWindowTitle; Result := 0; end; WM_SIZE: begin View.Width := LOWORD(lParam); View.Height := HIWORD(lParam); MoveWindow(View.VScroll, View.Width - SCROLLBAR_WIDTH, 0, SCROLLBAR_WIDTH, View.Height - SCROLLBAR_WIDTH, True); MoveWindow(View.HScroll, 0, View.Height - SCROLLBAR_WIDTH, View.Width - SCROLLBAR_WIDTH, SCROLLBAR_WIDTH, True); UpdateScrollRanges; InvalidateRect(hWnd, nil, True); Result := 0; end; WM_VSCROLL: OnVScroll(wParam); WM_HSCROLL: OnHScroll(wParam); WM_PAINT: OnPaint; WM_LBUTTONDOWN: OnMouseDown(LOWORD(lParam), HIWORD(lParam)); WM_SETFOCUS: begin CreateCaret(hWnd, 0, 2, CHAR_HEIGHT); ShowCaret(hWnd); UpdateCaret; Result := 0; end; WM_KILLFOCUS: begin HideCaret(hWnd); DestroyCaret; Result := 0; end; WM_CHAR: OnChar(wParam); WM_KEYDOWN: OnKeyDown(wParam); WM_DESTROY: begin PostQuitMessage(0); Result := 0; end; else Result := DefWindowProc(hWnd, Msg, wParam, lParam); end; end; // ==================== ТОЧКА ВХОДА ==================== var WC: TWndClass; begin FillChar(WC, SizeOf(WC), 0); WC.style := CS_HREDRAW or CS_VREDRAW; WC.lpfnWndProc := @WndProc; WC.hInstance := HInstance; WC.hbrBackground := GetStockObject(WHITE_BRUSH); WC.lpszClassName := 'SimpleEditor'; Windows.RegisterClass(WC); View.Handle := CreateWindow('SimpleEditor', 'Simple Editor', WS_OVERLAPPEDWINDOW or WS_CLIPCHILDREN, 230, 100, 800, 600, 0, 0, HInstance, nil); if View.Handle = 0 then Halt(1); ShowWindow(View.Handle, SW_SHOW); UpdateWindow(View.Handle); while GetMessage(Msg, 0, 0, 0) do begin TranslateMessage(Msg); DispatchMessage(Msg); end; end.
Я напоминаю, что ты споришь с тезисом о том, что в одно лицо без заимствования чужого кода нельзя создать программу, не уступающую существующим аналогам. Судя по размеру исполняемого файла и тому, что он написан на дельфи - это что-то около хеловорлда.
Покажи пальцем, что в этом хеловролде заимствовано из чужого кода? Код (Pascal): type TCell = record Ch: Char; Attr: Byte; end; TEditorModel = record Cells: array[0..MAX_LINES - 1, 0..MAX_COLS - 1] of TCell; LineCount: Integer; CurLine, CurCol: Integer; end; TEditorView = record Handle: HWND; VScroll, HScroll: HWND; ScrollLine, ScrollCol: Integer; MaxScrollLine, MaxScrollCol: Integer; Width, Height: Integer; end; Эти структуры я сам придумывал.
Давай помогу с формальной логикой: здесь три критерия, объединенных конъюнкцией: A = B & C & D Я сделал предположение, что критерий D не выполняется. Указал на это.
Анализ. Сам код: Становится ясно почему юный пациент не может использовать диз/отладчик, там непонятное