C++Builder 10.3 Community Edition を使用して、趣味でプログラミングをしていますが、NCデータを扱うソフトを作ってみようと計画しています。
C++Builderの「Memoコンポーメント」を利用すると、簡易なエディタ的な処理をさせる事ができますが、マウスを使わないでのカーソル操作や選択、検索などの処理をさせたかったので、調べてみたところある程度はできそうです。
関数化したので、覚書きとして、残しておきます。
EMBACADERO サポートサイト
発売元のサポートサイトに情報がありました。
C++Builderがサポートしていない機能は、 Performメソッド を使って、Windowsクラスへのメッセージを利用して実現させるようです。
関数プロトタイプ
上記のメッセージを参考に、関数を作成しました。
//----------------------------------------------------------------- // Memo // http://support.embarcadero.com/jp/article/35940 //--------------------------------------------------------------- // Memoの行数を返す int kMemoLineCount(TCustomMemo *memo); // Memoのカーソル行番号を返す int kMemoCurrentRowNumber(TCustomMemo *memo); // Memoの先頭にカーソルを移動する void kMemoMoveTop(TCustomMemo *memo); // Memoの指定行番号にカーソルを移動する、省略=トップ void kMemoMoveRowNumber(TCustomMemo *memo,int row=1); // Memoのカーソル行を指定行だけ下に移動する、省略=1行 void kMemoMoveDown(TCustomMemo *memo,int number=1); // Memoのカーソル行を指定行だけ上に移動する、省略=1行 void kMemoMoveUp(TCustomMemo *memo,int number=1); // Memoの指定行を選択する、省略=トップ void kMemoSelectRowNumber(TCustomMemo *memo,int row=1); // Memoの指定行の文字数、省略=カレント行 int kMemoGetCharCount(TCustomMemo *memo,int row=0); // Memoのカーソル行の指定位置から指定文字数を選択する、省略=すべて void kMemoSelectCurrentRow(TCustomMemo *memo,int start=0,int length=0); // Memoの1行下が見えるようにスクロールします。 void kMemoScrollLineDown(TCustomMemo *memo); // Memoの1行下が見えるようにスクロールします。 void kMemoScrollLineDown(TCustomMemo *memo); // Memoの1行上が見えるようにスクロールします void kMemoScrollLineUp(TCustomMemo *memo); // Memoの1ページ下が見えるようにスクロールします。 void kMemoScrollPageDown(TCustomMemo *memo); // Memoの1ページ上が見えるようにスクロールします。 void kMemoScrollPageUp(TCustomMemo *memo) ; // Memoの左右上下にスクロールさせます。 void kMemoScrollRowCol(TCustomMemo *memo,int col,int row); // Memoのカーソルより次へ文字列を検索します。 void kMemoSearchNext(TCustomMemo *memo,UnicodeString Key,bool select=true); // Memoのカーソルより前方向に文字列を検索します。 void kMemoSearchPrevious(TCustomMemo *memo,UnicodeString Key,bool select=true); // Memoの実際に目にみえている最初の行の行番号を返します(最初の行は0) int kMemoGetPageTopRow(TCustomMemo *memo); // RichEditの指定行の色を変更する TColor kRichEditChangeColor(TRichEdit *richedit,TColor color,int row=1);
関数の実装
//--------------------------------------------------------------
//-------- Memo ------------------------
//-------------------------------------------------------------
// TMemo の行数
int kMemoLineCount(TCustomMemo *memo)
{
int count = memo->Lines->Count;
return count;
}
// TMemo の現在のカーソル行位置(最初は1)
int kMemoCurrentRowNumber(TCustomMemo *memo)
{
int row = memo->Perform(EM_LINEFROMCHAR,-1,0)+1;
return row;
}
// Memoの先頭にカーソルを移動する
void kMemoMoveTop(TCustomMemo *memo)
{
memo->SelStart = memo->Perform(EM_LINEINDEX,0,0);
}
// Memoの指定行番号にカーソルを移動する、省略=トップ
void kMemoMoveRowNumber(TCustomMemo *memo,int row)
{
memo->SelStart = memo->Perform(EM_LINEINDEX,row-1,0);
memo->SetFocus();
}
// Memoのカーソル行を指定行だけ下に移動する、省略=1行
void kMemoMoveDown(TCustomMemo *memo,int number)
{
int current = kMemoCurrentRowNumber(memo);
kMemoMoveRowNumber(memo,current+number);
}
// Memoのカーソル行を指定行だけ上に移動する、省略=1行
void kMemoMoveUp(TCustomMemo *memo,int number)
{
int current = kMemoCurrentRowNumber(memo);
kMemoMoveRowNumber(memo,current-number);
}
// Memoの指定行を選択する、省略=トップ
void kMemoSelectRowNumber(TCustomMemo *memo,int row)
{
int count = memo->Lines->Count;
if(count<1) return;
UnicodeString str = memo->Lines->Strings[row-1];
int len = str.Length();
kMemoMoveRowNumber(memo,row);
memo->SelLength = len;
}
// Memoの指定行の文字数、省略=カレント行
int kMemoGetCharCount(TCustomMemo *memo,int row)
{
int rength = 0;
if(row == 0){
row = kMemoCurrentRowNumber(memo);
}
if(row>0){
rength = memo->Lines->Strings[row-1].Length();
}
return rength;
}
// Memoのカーソル行の指定位置から指定文字数を選択する、省略=すべて
void kMemoSelectCurrentRow(TCustomMemo *memo,int start,int length)
{
if(start==0 && length==0){
kMemoSelectRowNumber(memo);
return;
}
int row = kMemoCurrentRowNumber(memo);
int len = kMemoGetCharCount(memo,row);
kMemoMoveRowNumber(memo,row);
if((start+length)>len){
length = len-start+1;
}
memo->SelStart += (start-1);
memo->SelLength = length;
}
// Memoの1行下が見えるようにスクロールします。
void kMemoScrollLineDown(TCustomMemo *memo)
{
memo->Perform(EM_SCROLL, SB_LINEDOWN, 0);
}
// Memoの1行上が見えるようにスクロールします
void kMemoScrollLineUp(TCustomMemo *memo)
{
memo->Perform(EM_SCROLL, SB_LINEUP, 0);
}
// Memoの1ページ下が見えるようにスクロールします。
void kMemoScrollPageDown(TCustomMemo *memo)
{
memo->Perform(EM_SCROLL, SB_PAGEDOWN, 0);
}
// Memoの1ページ上が見えるようにスクロールします。
void kMemoScrollPageUp(TCustomMemo *memo)
{
memo->Perform(EM_SCROLL, SB_PAGEUP, 0);
}
// Memoの上下左右にスクロールさせます。
void kMemoScrollRowCol(TCustomMemo *memo,int row,int col)
{
memo->Perform(EM_LINESCROLL, row, col);
}
// Memoの実際に目にみえている最初の行の行番号を返します(最初の行は1)
int kMemoGetPageTopRow(TCustomMemo *memo)
{
int row = memo->Perform(EM_GETFIRSTVISIBLELINE, 0, 0);
return row+1;
}
// Memoのカーソルより次へ文字列を検索します。
void kMemoSearchNext(TCustomMemo *memo,UnicodeString Key,bool select)
{
int count = memo->Lines->Count;
int current = kMemoCurrentRowNumber(memo);
UnicodeString str;
int pos;
int len = Key.Length();
for(int i= current;iLines->Strings[i];
pos = str.Pos(Key);
if(pos){
kMemoMoveRowNumber(memo,i+1);
if(select){
kMemoSelectCurrentRow(memo,pos,len);
}
break;
}
}
}
// Memoのカーソルより手前に文字列を検索します。
void kMemoSearchPrevious(TCustomMemo *memo,UnicodeString Key,bool select)
{
int count = memo->Lines->Count;
int current = kMemoCurrentRowNumber(memo)-1;
UnicodeString str;
int pos;
int len = Key.Length();
for(int i= current;i>=0;i--){
str = memo->Lines->Strings[i-1];
pos = str.Pos(Key);
if(pos){
kMemoMoveRowNumber(memo,i);
if(select){
kMemoSelectCurrentRow(memo,pos,len);
}
break;
}
}
}
// RichEditの指定行の色を変更する
TColor kRichEditChangeColor(TRichEdit *redit,TColor color,int row)
{
TColor cl = redit->SelAttributes->Color;
kMemoSelectRowNumber(redit,row);
redit->SelAttributes->Color = color;
redit->SelLength = 0;
return cl;
}
完成
とりあえず、作ってみましたが、簡単にしか検証していません。
もし、使用する場合には、ご注意ください。


コメント