ApplyStyleConv..(rv_BackColor) - error only in rveTable

General TRichView support forum. Please post your questions here
Post Reply
j&b
Posts: 184
Joined: Mon Sep 05, 2005 1:35 pm

ApplyStyleConv..(rv_BackColor) - error only in rveTable

Post by j&b »

I want to mark a text with backcolor clYellow

All is ok if text is in memo, but only if text is in a rveTable I get an error-hint. After closing error-window progam runs without error.



procedure TForm1.memoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
{
var r,c,rs,cs: Integer;
Cell: TRVTableCellData;
Table: TRVTableItemInfo;
}
begin
//…
if (ssCtrl in Shift) then begin //Strg+key
if (key=vk_F4) or (key=vk_F10) then begin
try //Hintergrundfarbe
if (key=vk_F4) then cd.color:= clWhite
else if (key=vk_F10) then cd.color:= clYellow; //gelb

//error only appears in rveTable
Memo.ApplyStyleConversion(rv_BackCOLOR);
(I get the same error with Memo.ApplyStyleConversion(rv_COLOR);.

memo.deselect;
finally
if query1.state in [dsEdit, dsInsert] then query1.Post;
end;
memo.setfocus;
exit;
end;
end;



Program stops in unit RichView:

function TCustomRichView.GetTabNavigation:TRVTabNavigationType;
begin
Result := RVData.TabNavigation;
end;
    Sergey Tkachenko
    Site Admin
    Posts: 17569
    Joined: Sat Aug 27, 2005 10:28 am
    Contact:

    Post by Sergey Tkachenko »

    If you remove the code
    memo.deselect;
    finally
    if query1.state in [dsEdit, dsInsert] then query1.Post;
    end;
    memo.setfocus;
    exit;
    end;
    end;

    Does the error still exist?
    j&b
    Posts: 184
    Joined: Mon Sep 05, 2005 1:35 pm

    Post by j&b »

    Thank you. All runs.

    I only have to remove "memo.deselect"

    I deselect memo about key:= vk_right --> Caret jumps to next cell

    Now I am looking for a key which deselect memo but remains at the position.
    j&b
    Posts: 184
    Joined: Mon Sep 05, 2005 1:35 pm

    memo.deselect

    Post by j&b »

    Memo.ApplyStyleConversion(rv_BackCOLOR);
    if memo.GetCurrentItemEx(TRVTableItemInfo, rve, TCustomRVItemInfo(rveTable)) then key:= vk_right
    else memo.deselect;

    to deselect memo about key:= vk_right (or another key) is not the right way.

    Do you know another way ?
    Sergey Tkachenko
    Site Admin
    Posts: 17569
    Joined: Sat Aug 27, 2005 10:28 am
    Contact:

    Post by Sergey Tkachenko »

    It is not allowed to destroy cell inplace editor inside OnKeyDown event.
    Deselect destroys it,
    The best solution: instead of using OnKeyDown, create an action or a menu item with Ctrl+F4 and Ctrl+F10 shortcuts.
    j&b
    Posts: 184
    Joined: Mon Sep 05, 2005 1:35 pm

    create a menu item with Ctrl+F4 and Ctrl+F10 shortcuts

    Post by j&b »

    Thank you, Sergey.


    >>create a menu item with Ctrl+F4 and Ctrl+F10 shortcuts. //do you mean AND and not OR ?

    All trials don’t memo.deselect. Can you tell me what I have to write?



    procedure TForm1.memoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);

    begin

    Memo.ApplyStyleConversion(rv_BackCOLOR);
    if memo.GetCurrentItemEx(TRVTableItemInfo, rve, TCustomRVItemInfo(rveTable)) then sendkeys(‘^{F4}, true) else memo.deselect;
    exit;

    end;


    procedure TForm1.testen1Click(Sender: TObject); //called up by Strg+F4
    begin
    ???? //memo.deselect  produces the same error
    end;
    Sergey Tkachenko
    Site Admin
    Posts: 17569
    Joined: Sat Aug 27, 2005 10:28 am
    Contact:

    Post by Sergey Tkachenko »

    Using SendKeys is not a solution. It calls SendMessage inside, so the key message is processed INSIDE SendKeys. I.e., it is the same as before, you call testen1Click (and hence memo.Deselect) from inside memoKeyDown.

    There are only two solutions

    1) Do not use OnKeyDown, use only buttons/actions with shortcuts.
    2) If you use OnKeyDown, but moves the code from it to another procedure, initiated using PostMessage.

    I.e.
    - define some constant greater than WM_USER

    Code: Select all

    const 
      WM_MYCOMMAND = WM_USER + 10; 
    - add in the form declaration:

    Code: Select all

    type 
    ...
      TForm1 = class(TForm) 
        ... 
        procedure WMMyCommand(var Msg: TMessage); message 
    WM_MYCOMMAND;
    - implementation:

    Code: Select all

    procedure TForm1.WMMyCommand(var Msg: TMessage); 
    begin 
      call memo.Deselect and other commands here
    end;
    - in OnKeyPress:

    Code: Select all

    procedure TForm1.memoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); 
    ...
    begin 
    ...
      PostMessage(Handle, WM_MYCOMMAND, 0, 0);
    ...
    end; 
    j&b
    Posts: 184
    Joined: Mon Sep 05, 2005 1:35 pm

    Post by j&b »

    That works, BUT

    cursor is beneath table and not at the end of text which was marked before.

    Therefore I add in procedure TForm1.WMMyCommand rveTable.xxx

    procedure TForm1.WMMyCommand(var Msg: TMessage);
    begin
    rveTable.GetEditedCell(rveTzeile1,rveTspalte1);
    memo.Deselect;
    rveTable.EditCell(rveTzeile1,rveTspalte1);
    // ??? go to the end of text which was marked before
    end;

    Now cursor stands at the first position of the cell and not at the end of text which was marked before.

    What's to do ?
    Sergey Tkachenko
    Site Admin
    Posts: 17569
    Joined: Sat Aug 27, 2005 10:28 am
    Contact:

    Post by Sergey Tkachenko »

    Sorry, what do you want to do by this code?
    Deselect and then select again?

    If you just want to make the selection empty without moving the caret, the code is:

    Code: Select all

    var ItemNo1, Offs1, ItemNo2, Offs2: Integer;
    
    memo.TopLevelEditor.GetSelectionBounds(ItemNo1, Offs1, ItemNo2, Offs2, False);
    if (ItemNo1>=0) then
      memo.TopLevelEditor.SetSelectionBounds(ItemNo2, Offs2, ItemNo2, Offs2);
    This code does not destroy the cell inplace editor, so it can be called in OnKeyDown.
    j&b
    Posts: 184
    Joined: Mon Sep 05, 2005 1:35 pm

    Post by j&b »

    procedure TForm1.memoKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    ...
    begin
    ...
    if (ssCtrl in Shift) and (ssShift in Shift) then begin //Strg+Shift+key
    ...
    end else if (ssShift in Shift) then begin //Shift+key
    ...
    end else if (ssCtrl in Shift) and (ssShift in Shift) then begin //Strg+key
    if (key=vk_F10) then
    cd.color:= clYellow;
    Memo.ApplyStyleConversion(rv_backCOLOR);
    if memo.GetCurrentItemEx(TRVTableItemInfo, rve, TCustomRVItemInfo(rveTable)) then PostMessage(Handle, WM_MYCOMMAND,0,0)
    else memo.deselect;
    sysUtils.abort; //damit Cursor wieder 'blinkt'
    exit;
    end else if (key=vk_return) then begin ....


    procedure TForm1.WMMyCommand(var Msg: TMessage);
    var ItemNo1, Offs1, ItemNo2, Offs2: Integer;
    begin
    rveTable.GetEditedCell(rveTzeile1,rveTspalte1);
    memo.TopLevelEditor.GetSelectionBounds(ItemNo1, Offs1, ItemNo2, Offs2, False);
    memo.Deselect;
    rveTable.EditCell(rveTzeile1,rveTspalte1); //rveTable.GetEditedCell+rveTable.EditCell: Cursor steht im Memo
    if (ItemNo1>=0) then memo.TopLevelEditor.SetSelectionBounds(ItemNo2, Offs2, ItemNo2, Offs2); //damit Cursor hinter dem ehemals Markierten steht
    end;
    Post Reply