Page 1 of 1
ApplyStyleConv..(rv_BackColor) - error only in rveTable
Posted: Fri May 18, 2012 12:58 pm
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;
Posted: Fri May 18, 2012 1:38 pm
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?
Posted: Fri May 18, 2012 2:28 pm
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.
memo.deselect
Posted: Fri May 18, 2012 3:28 pm
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 ?
Posted: Sat May 19, 2012 7:59 pm
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.
create a menu item with Ctrl+F4 and Ctrl+F10 shortcuts
Posted: Sun May 20, 2012 9:01 am
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;
Posted: Sun May 20, 2012 2:48 pm
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;
Posted: Sun May 20, 2012 4:25 pm
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 ?
Posted: Sun May 20, 2012 5:11 pm
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.
Posted: Tue May 22, 2012 4:19 pm
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;