PDA

View Full Version : سوال: چطور توی Memo مثل ویرایشگر کد دلفی با رفتن به سطر بعد به محل زیر سر سطر جاری منتقل بشم؟



mbshareat
جمعه 30 تیر 1391, 20:25 عصر
سلام علیکم
پیشاپیش ماه مبارک رمضان رو تبریک میگم.
حتما دیدین که وقتی که دارین کد برنامه رو تایپ می کنین اگه تورفتگی و دندانه در کد باشه با فشار Ent وقتی به سطر بعد میریم مکان نما به جای اینکه به سر سطر بعد بره به زیر مکانی میره که کد سطر جاری شروع شده.
من میخوام توی ممو چنین قابلیتی رو با فشار Ctrl+Ent توی Memo داشته باشم.
یه سوال مرتبط: آیا Memo راهی برای فهمیدن شماره سطر و محتوای سطر جاری در اختیار میذاره؟

سعید صابری
جمعه 30 تیر 1391, 20:29 عصر
فکر کنم advmemo از مجموعه tms چنین قابلتی را داشته باشه
http://www.tmssoftware.com/site/advmemo.asp

mbshareat
جمعه 30 تیر 1391, 20:35 عصر
سلام
از اینکه ظرف چند دقیقه جواب دادین ممنونم.
من دوتا مشکل با کامپوننتهای Tms دارم: رایگان نیستند و حجیمند و من مشترک DialUp هستم.
اگه ممکنه یه راه برای کار کردن با همون مموی دلفی بفرمایین.

Ananas
جمعه 30 تیر 1391, 20:51 عصر
سلام.

پیشاپیش ماه مبارک رمضان رو تبریک میگم.
به همچنین. زنده باشی.
____________________
برای کار با خط های نوشته شده از TMemo.Lines استفاده کن. برای رفتن به خط بعد و فاصله از اول خط هم از space استفاده کن. مثلا ببین خط بالا چند تا space اولش هست، به همون تعداد space اضافه کن.

سعید صابری
جمعه 30 تیر 1391, 20:58 عصر
زیاد هم حجیم نیست 24 MB.البته خوب واسه دیال زیاده!
اما قیمت که برای ما رایگانه.
برای خود MEMO همه کار سختی نیست فاصله خالی خود قبل اندازه بگیر.خط بعد هم همون اندازه فاصله خالی(کاراکتر SPACE) ایجاد کن

mbshareat
جمعه 30 تیر 1391, 21:01 عصر
سلام
خوب این که فرمودین یعنی چی؟
مگه ممو گزارش میگنه که چه خطی هستیم و کجای سطر هستیم؟

Ananas
جمعه 30 تیر 1391, 21:08 عصر
بله.
شما توابعی که شی TMemo داره مطالعه و برسی کن خیلی امکانات داره که همین کارها رو انجام میده. مثلا :

Memo1.SelLength
Memo1.SelStart
Memo1.SelText
Memo1.SetSelText
.
.
.

سعید صابری
جمعه 30 تیر 1391, 21:12 عصر
فکر نکنم ولی شما می تونید بدستش بیارید

Line := Memo1.Perform(EM_LINEFROMCHAR,SelStart, 0) ;

Felony
جمعه 30 تیر 1391, 21:14 عصر
برای به دست آوردن Index سطر جاری :

CurrLine := Memo1.Perform(EM_LINEFROMCHAR, Memo1.SelStart, 0);

به دست آوردن Index ستون جاری :

CurrColumn := Memo1.SelStart - Memo1.Perform(EM_LINEINDEX, CurrLine, 0);

mbshareat
جمعه 30 تیر 1391, 21:35 عصر
سلام
ممنون. تاحالا با این سرعت اینقدر جواب نیومده بود.
آقای صابری کدتون با یه ریزه دستکاری درست کار میکنه:
CurrLine := Memo1.Perform(EM_LINEFROMCHAR,Memo1.SelStart, 0) ;
فکر می کردم آخرش باید کارکترها رو بشمرم. Mahan-1363 از شما خیلی ممنونم.
کاش من هم با Perform آشنایی داشتم. ظاهرا بیشتر از SendMessage تنوع داره و اختصاصی تر هم هست.
یه سوال دیگه هم دارم: برای اضافه کرن پنج تا فاصله حتما باید چنین کدی بنویسم؟
P:=LinesMemo.SelStart;
S:=LinesMemo.Text;
Insert(' ',S,P+1);
LinesMemo.Text:=S;
LinesMemo.SelStart:=P+5;

یه سوال دیگه هم در مورد ممو دارم لطفا به تاپیک جدیدم (http://barnamenevis.org/showthread.php?352201-%D8%A2%DB%8C%D8%A7-%D8%B1%D8%A7%D9%87%DB%8C-%D9%87%D8%B3%D8%AA-%DA%A9%D9%87-%D8%AA%D9%88%DB%8C-%D9%85%D9%85%D9%88-%D8%A8%D8%A7-%D9%81%D8%B4%D8%A7%D8%B1-Tab-%D9%BE%D9%86%D8%AC-%D8%AA%D8%A7-%D9%81%D8%A7%D8%B5%D9%84%D9%87-%D8%A7%D8%B6%D8%A7%D9%81%D9%87-%DA%A9%D9%86%DB%8C%D9%85%D8%9F&p=1552956#post1552956) هم سر بزنین!

Ananas
جمعه 30 تیر 1391, 22:01 عصر
Memo1.SetSelText(' ');

younes221
جمعه 30 تیر 1391, 22:12 عصر
سلام ، تا حالا در دلفی زیر برنامه ای ندیدم که یک رشته رو بهش بدی و تعدادی Space رو بهش اضافه کنه ، ولی میشه خودمون یک زیر برنامه بنویسیم و این کارو واسمون انجام بده مثل زیر :


procedure TForm2.SetSpace(var S: String; Count: Integer);
var
counter:Integer;
begin
for counter := 0 to Count-1 do
S:=' '+S;
end;

زیر برنامه بالا یک رشته رو میگیره و به تعداد دلخواه ( از طریق پارامتر Count ) فضای خالی به ابتدای رشته اضافه میکنه. البته میشد زیر برنامه رو بسط داد تا در هرجایی که دلمون خواست Space اضافه کنه ولی اون دیگه به عهده خودتون.

Felony
جمعه 30 تیر 1391, 22:17 عصر
تا حالا در دلفی زیر برنامه ای ندیدم که یک رشته رو بهش بدی و تعدادی Space رو بهش اضافه کنه
اگر میخواین به اول یا آخر رشته یک متن رو به تعداد دفعات دلخواه اضافه کنید میتونید از تابع DupeString از کتابخانه StrUtils استفاده کنید ؛ مثلا همون کدی که بالا نوشتید میشه :

procedure TForm2.SetSpace(var S: String; Count: Integer);
begin
S:= DupeString(' ', Count) + S;
end;

Ananas
جمعه 30 تیر 1391, 22:32 عصر
این کد هم یک بار حافظه میگیره بعد space یا هر چی بخواید براتون پر میکنه :

function SpaceString(const count_ : Integer; char_ : Char):string;
var
ach : array of Char;
I: Integer;
begin
SetLength(ach, count_ + 1);
for I := 0 to High(ach) do
ach[I] := char_;
ach[count_] := Char(0);
Result := PWideChar(ach);
end;

اگه تو حلقه طول string تغییر نکنه بهتره.

mbshareat
جمعه 30 تیر 1391, 22:56 عصر
با سلام مجدد
آقای Ananas کد شما تو دلفی قدیمی من کار نمی کنه و این کد رو جایگزین کردم:
Memo1.SetSelTextBuf(PChar(' '));
برای اضافه کردن رشته ای به رشته دیگه از Insert استفاده کنین راحت تره؛ اما بحث کار با Memo بود و شبیه سازی Tab!
توی ممو کل سطرها یه رشته هستش (Memo.Text) نه یه سطر رشته جدا باشه مگر اینکه برنامه بدونه کدوم سطر هستین که از Lines استفاده کنین که من راه دستیابی به شماره سطر رو نمی دونستم.

Ananas
جمعه 30 تیر 1391, 23:10 عصر
برای اضافه کردن رشته ای به رشته دیگه از Insert استفاده کنین راحت تره؛
آخه insert یه اشکالی داره اینکه دوباره SelStart رو باید تنظیم کنیم. موقع نوشتن وسط متن، تابع SetSelStart یا همون که گفتید خوبه.

mbshareat
جمعه 30 تیر 1391, 23:21 عصر
آقا محمد منظورم استفاده از Insert در Memo نبود. اصلا بحث اون وسط در مورد رشته بود هر رشته ای!

Ananas
شنبه 31 تیر 1391, 01:05 صبح
بله متوجهم. درست می گید. منظورم فقط memo بود.
کلا string ها رو تا حد امکان بهتره کمتر " تغییر سایز بدیم و یا کپی اضافی بگیریم یا با operator های جمع و تفریق باهاشون بازی کنیم" بخاطر سرعت. مثلا اگر عملی رو میشه یکجا انجام داد نیایم تو چند مرحله تیکه تیکه string رو تغییر بدیم و یا خود memo رو برای کمتر update شدن text اش رو بگیریم و همونطور که گفتید با insert یا هر چیزی تغییرات انجام بشه بعد یکجا به memo انتقال بدیم. ولی فکر کنم تغییرات کوچیک داخل خود memo سریع تر باشه تا گرفتن کل متن و دوباره تحویل دادن کل متن به memo. ولی در کل Update شدن Memo خیلی زمان بر هست. من یک ماشین حساب نوشتم که مراحل محاسبات از طریق memo گزارش میشه (شاید سورسشو آپلود کنم) و با فعال کردن گزارش مراحل تو memo سرعتش خیلی خیلی پایین میاد یعنی چند برابر محاسبات Update اون Memo طول میکشه (البته تو رقم های کم اینطوره و تو رقم های بالا دیگه memo خیلی تاثیری نداره چون محاسبات خیلی طولانی میشه).
یه چیز دیگه اینکه اگه memo کوچیکتر باشه یعنی متن کمتری رو بتونه داخل کادرش نمایش بده و بقیه ی متن بره بیرون سرعتش بیشتر میشه. و یا اینکه متن خیلی بزرگ باشه که داخل کادر memo کاراکتر های کمتری جا بگیره به سرعت خیلی تاثیر داره.
ببخشید نوشته هام از موضوع تاپیک یکمی منحرف شد.

mbshareat
شنبه 31 تیر 1391, 04:11 صبح
ان شاء الله من هم نمایشگر ساده متنم رو تو تاپیک "سورسهاي نمونه آموزشي" آپلود می کنم.

mbshareat
شنبه 31 تیر 1391, 09:59 صبح
نتیجه گیری:
با کد زیر با فشار Enter نتیجه ای مثل محیط ویرایشگر کد دلفی بدست میاریم:

procedure TEditForm.Memo1KeyPress(Sender: TObject; var Key: Char);
Var
I,P:Word;
CurLine,CurColumn,LeadingSpc,LineStartPos:Integer;
begin
If Key=#13 then
Begin
Key:=#0;
CurLine :=Memo1.Perform(EM_LINEFROMCHAR,Memo1.SelStart,0);
LineStartPos:=Memo1.Perform(EM_LINEINDEX,CurLine,0 );
CurColumn := Memo1.SelStart-LineStartPos;
LeadingSpc:=0;
For I:=1 To CurColumn Do
If Memo1.Lines[CurLine][I]=' ' then
Inc(LeadingSpc)
Else
Break;
P:=LineStartPos+CurColumn;
Memo1.SelStart:=P;
Memo1.SetSelTextBuf(PChar(#13#10+DupeString(' ',LeadingSpc)));
End;
end;

mbshareat
شنبه 31 تیر 1391, 15:04 عصر
با سلام مجدد خدمت دوستان عزیز
این هم لینک برنامه (http://barnamenevis.org/showthread.php?209792-%D8%B3%D9%88%D8%B1%D8%B3%D9%87%D8%A7%D9%8A-%D9%86%D9%85%D9%88%D9%86%D9%87-%D8%A2%D9%85%D9%88%D8%B2%D8%B4%D9%8A&p=1553445&viewfull=1#post1553445)