PDA

View Full Version : حرفه ای: ساخت پلاگین برای MMB



loo30fer
پنج شنبه 09 دی 1389, 18:30 عصر
با سلام
میخواستم اگه امکان داره نحوه صحیح و اصلی ساخت پلاگین برای مولتی مدیا بیلدر رو خیلی مقدماتی بگین که برای افرادی مثل من راحت باشه , دلیل اینکه هم که گفتم نحوه صحیح و اصلی به دلیل اینکه من سورس های پلاگین های مختلفی رو دیدم که هرکدوم با یک روش مختلفی نوشته شده بود و بعد از کمپایل اختلاف حجم خیلی زیادی داشتن البته این رو هم بگم که تمام Function و دستورات Function و Uses های اضافی رو حذف کرده بودم و بر خلاف این پلاگین هایی که من سورسشون رو داشتم با داشتن 6 الی 13 تا Functions حجمی حدود 300 کیلوبایت که کارایی خاصی هم نداشتن ولی پلاگین Miscy که با دلفی هم نوشته شده بود با وجود 157 Functions فقط حجمش 571 کیلوبایت بود
با تشکر از دوستان و اساتید برنامه نویس

Felony
جمعه 10 دی 1389, 08:44 صبح
برای پلاگین نویسی برای MMB نیاز به کیت توسعه نرم افزاری ( SDK ) مربوط به اون دارید ، البته این SDK فقط تا دلفی 7 توسعه داده شد و بعد شرکت Media Chance ورشکست شد ؛ این کتابخانه نقش واسط بین پلاگین شما و MMB رو بر عهده داره ، پس شما برای تبادل اطلاعات بین پلاگین و برنامه نوشته شده با MMB باید از دستورات این کتابخانه استفاده کنید ، این کتابخانه توابع مختلفی ارائه میکنه که من نحوه کار با 4 تا از اصلی ترین هاشون رو بهتون میگم .

1- برای دریافت رشته از برنامه MMB به پلاگین باید از TextInput که به صورت یک آرایه تعریف شده استفاده کنید ، TextInput در کد بالا به صورت یک آرایه 5 خونه ای تعریف شده که هر خونش میتونه حاوی یک رشته خاص باشه ، پس با توجه به این توضیح شما میتونید در یک زمان 5 تا رشته رو توسط برنامه MMB تون به پلاگین بفرستید که البته میشه تعداد این رشته ها رو با تغییر در کد بالا افزایش داد که کار سختی هم نیست .

2- برای ارسال رشته از پلاگین به برنامه MMB از TextOutput استفاده میشه که به صورت یک متغییر تعریف شده و در یک زمان مشخص شما میتونید فقط یک رشته رو از پلاکین به برنامه MMB بفرستید که اون هم با ترفندهایی قابل تغییر هست .

3- برای ارسال عدد از برنامه پلاگین از NumInput که به صورت یک آرایه 5 خونه ای هست استفاده میشه ، پس در یک زمان واحد میتونید 5 عدد مختلف رو از برنامه به پلاگین ارسال کنید که قابل تغییر هم هست .

4- برای ارسال عدد از پلاگین به برنامه از NumOutput که یک متغییر هست استفاده میشه .

به عنوان نمونه کد زیر نام و نام خانوادگی رو تو 2 تا رشته جدا از برنامه میگیره و به هم اتصال میدشون و در آخر به برنامه بر میگردونه :

Procedure Test; cdecl;
var
FName, LName, FullName: String;
begin
FName:= TextInput[2];
LName:= TextInput[1];
FullName:= FName + ' ' + LName;
TextOutput:= FullName;
end;
یا کد زیر 2 تا عدد رو از برنامه میگیره و با هم جمع میکنه و به برنامه بر میگردونه :

Procedure Test; cdecl;
var
Num1, Num2, Answer: Integer;
begin
Num1:= NumInput[2];
Num2:= NumInput[1];
Answer:= Num1 + Num2;
NumOutput:= Answer;
end;

این 4 تا رایج ترین موارد برای پلاگین نویسی برای MMB هستن .

- برای اینکه برنامه MMB بتونه توابع مورد نظرتون رو از داخل پلاگین صدا بزنه حتما باید دایرکتیو cdecl رو در آخر توابع ذکیر بکنید .

- در آخر کار باید لیست توابع مورد نیازتون رو برای استفاده برنامه export بکنید ( به نمونه ضمیمه شده مراجعه کنید )

- من SDK رو به 2 صورت درآوردم ، یکی برای پلاگین های non-Visual که نیازی به فرم ندارن و دیگری برای پلاگین های Visual که نیاز به فرم و رسم اشیاء مختلف دارن ؛ این کار برای کاهش حجم پلاگین تولید شده هست ؛ برای ساخت پلاگین های Visual کافیه از SDK مربوط به پلاگین Visual استفاده کنید رو فرم اشیاء مورد نظر رو بزارید .

- برای کم شدن حجم پلاگین از پکر هایی مثل UPX استفاده کنید .

- قبلا با توجه به نیازم این SDK رو برای Delphi 2010 توسعه دادم ولی جایی انتشار نداده بودمش که در ضمیمه به همراه یه نمونه پلاگین قرار دادمش .

javad p
یک شنبه 12 دی 1389, 15:32 عصر
و بعد از کمپایل اختلاف حجم خیلی زیادی داشتن البته این رو هم بگم که تمام Function و دستورات Function و Uses های اضافی رو حذف کرده بودم و بر خلاف این پلاگین هایی که من سورسشون رو داشتم با داشتن 6 الی 13 تا Functions حجمی حدود 300 کیلوبایت که کارایی خاصی هم نداشتن ولی پلاگین Miscy که با دلفی هم نوشته شده بود با وجود 157 Functions فقط حجمش 571 کیلوبایت بود
افزایش حجم مربوط به تعداد Functions ها نیست (البته نه کاملا) ولی به میزان خیلی کمی با این مورد مرتبط هست
شما بهتره علاوه بر رعایت موارد پست بالا برای کاهش حجم به کتابخانه هایی که تو فایل هستند دقت کنید. افزایش اصلی حجم به دلیل استفاده کردن از کتابخانه های مختلف هست.

loo30fer
یک شنبه 12 دی 1389, 15:55 عصر
بله دوست عزیز درسته منم تو پستم اشاره کرده بودم که
تمام Function و دستورات Function و Uses های اضافی رو حذف کرده بودم و به سورس آماده اضافه کردن دستورات تبدیلشون کرده بودم و یکی از دلایلی هم که به خاطرش تاکید داشتم روش اصلی پلاگین نویسی گفته بشه اینکه هرکی سورس کار من رو دید گیج نشه که این چه نوع پلاگین نویسی هستش و نتونه کدها رو درک کنه و برای کاربران دیگه هم که روش پلاگین نویسی رو میخونن براشون راحتتر و قابل درک باشه

javad p
یک شنبه 12 دی 1389, 16:52 عصر
یکی از دلایلی هم که به خاطرش تاکید داشتم روش اصلی پلاگین نویسی گفته بشه اینکه هرکی سورس کار من رو دید گیج نشه که این چه نوع پلاگین نویسی هستش و نتونه کدها رو درک کنه
زیاد فرق نمیکنه
چون شما نمیتونید از چهارچوب کلی SDK که Media Chance برای این کار در نظر گرفته خارج بشید
اون تفاوتها تو نوشتن plugin ها هم اصلا تو اصل قضیه تاثیری نداره و کسی که دلفی بلد باشه تو اون کدها گیج نمیشه!!

loo30fer
یک شنبه 12 دی 1389, 17:45 عصر
کسی که دلفی بلد باشه تو اون کدها گیج نمیشه!!
خوب کسی هم که دلفی بلد باشه حتما پلاگین نویسی برای MMB رو بلده و دیگه نیازی به سورس من نداره من این تاپیک هم رو ایجاد کردم برای افراد مبتدی مثل خودم که زیاد با دلفی آشنایی ندارین و میخوان با نحوه پلاگین نویسی آشنا بشن پس اگه افرادی مثل خودم سورس ها رو نگاه کنن یکم گیج میشن

جناب تاجیک اگه امکان هم داره در مورد هریک از Function های خود پلاگین توضیحی بدین که کاراییش چیه و چرا استفاده میشه (,...SetFile,Draw,SetParentwindow)

Felony
یک شنبه 12 دی 1389, 18:26 عصر
GetColor : برای تبدیل یک رشته رنگ به TColor .

GetWindowsTempDir : برای پرفتن مسیر پوشه Temp ویندوز .

GetWindowsDir : گرفتن مسیر پوشه ویندوز .

GetSystemDir : گرفتن مسیر پوشه System32 .

CallMMBScript : اجرای یک کد اسکریپت از داخل پلاگین .

GetMMBScriptInt : گرفتن مقدار بازکشتی از یک اسکریپت ( عددی ) .

GetMMBScriptStr : گرفتن مقدار بازگشتی از یک اسکریپت ( رشته ) .

hMMBWindow : هندل پنجره برنامه MMB که به وسیله اون میتونید یک شئ یا ... رو به صورت RunTime روش بسازید .

HasIntDlg : با 1 کردن مقدار Result در کد زیر دکمه Properties در قسمت تنضیمات پلاگین تو MMB فعال میشه .


function HasIntDlg: integer; cdecl;
begin
Result:=0;
end;

وقتی دکمه Properties زده شد میتونید یک فرم به کاربر به عنوان تنضیمات پلاگین نمایش بدید یا ... ( تو پلاگین Silver Access که قبلا نوشتم نمونش هست ) ، برای این کار کودتون رو باید در روال زیر بنویسید :

function _Interface: pChar; cdecl;
begin
//MessageBox(FindWindow('#32770','MMB PlugIn'),'You can here add e.g.: form with plugin options...','PlugIn Properties',0);
Result := nil;
end;

موفق باشید .

loo30fer
یک شنبه 12 دی 1389, 21:08 عصر
تشکر , ببخشید ولی من منظورم رو بد رسوندم منظور من Function های مورد نیاز MMB بود برای مثال :

SetFile,
GetFile,
SetData,
GetData,
SetPath,
Copyright,
GetShortInfo,
GetInfo
GetType,
SetParentwindow,
Draw;

loo30fer
جمعه 24 دی 1389, 16:11 عصر
جناب تاجیک اگه امکان داره در مورد کار Function خود MMB که مطرح کردم توضیحی بدین با تشکر

Felony
شنبه 25 دی 1389, 01:57 صبح
SetFile,
GetFile,
SetData,
GetData,
خود بیلدر باهاشون کار میکنه و به برنامه نویس مربوط نمیشه ، اگر تو نحوه تعریفشون تو SDK هم دقت کنی میبینید که وقتی متنی یا عددی رو به پلاگین ارسال و یا از پلاگین دریافت میکنید این توابع صدا زده میشه ؛ البته برای بعضی پلاگین های بزرگ و پیچیده که نیاز به ارسال یا دریافت پارامترهای بیشتر رو دارید میتونید این تعاریف رو بر اساس کدهای خودش ویرایش کنید .


SetPath
یک متغییر رشته ای رو به عنوان مسیر مقدار دهی میکنه که کاربرد خاصی نداره ؛ دقت کنید که این SDK ها توسط خود Mediachance ارائه نشده بلکه فقط نسخه اولیه توسط شرکت ارائه شده و این نسخه هایی که دست شماست توسط کاربران توسعه داده شده و هر کاربر بسته به نیازش چیزهایی بهش اضافه کرده که ممکنه استاندارد نباشه ؛ Mediachance فقط برای نسخه اولیه بیلدر که امکان استفاده از پلاگین داشت SDK ارائه کرد و برای نسخه های بعدی کاربرانش SDK ها رو توسعه میدادن ، مثل همین SDK نسخه 2010 که براتون ضمیمه کردمش .


Copyright,
متن Copyright مربوط به پلاگین رو به صورت رشته بر میگردونه ؛ این متن رو در قسمت بالای کدهای SDK میتونید برای خودتون تغییر بدید :

//PlugIn Info
const
PluginCopyright = 'Copyright here';


GetInfo
اطلاعات پلاگین رو به صورت رشته بر میگردونه ( مثل Copyright که بالا توضیح دادم میتونید تغییرش بدید ) .


GetType
برای استفاده خود بیلدر هست که Mode پلاگین رو به بیلدر اطلاع میده .


SetParentwindow
برای تعیین Mode پلاگین هست که خود بیلدر ازش استفاده میکنه .

Draw
اگر پلاگین حاوی فرم باشه باعث رسم فرم در صفحه پلاگین بیلدر در زمان اجرا برنامه میشه ، اگر پلاگینتون فرم نداره میتونید حذف یا کامنتش کنید .

loo30fer
پنج شنبه 07 بهمن 1389, 00:01 صبح
ببخشید جناب تاجیک امکان داره در مورد فانکشن SetParentwindow توضیح کاملتری بدین که کارش دقیق چیه و این Mode چی هست و چیکار میکنه و وجودش آیا تو پلاگین الزامیه ؟

و من وقتی سورس پلاگین های مختلف رو نگاه میکنم میبینم همیشه این Uses ها رو بهش دادن که Classes SysUtils, Variants و طبق ساختار جالب دلفی هنگام کمپایل اگه یه Uses یا دستوری کم یا اشتباه باشه خطا میگیره و اجازه کمپایل نمیده و من همیشه هم این Uses ها رو حذف میکنم و میخواهم کمپایل کنم بدون هیچ مشکل یا خطا گیری توسط دلفی کمپایل میشه حالا میخواستم بدونم آیا استفاده از این Uses ها الزامی است و بعد از حذفشون باعث ایجاد اشکالی میشه چون بعد از حذفشون باعث کم شدن حجم محسوس پلاگین میشه

با تشکر

Felony
پنج شنبه 07 بهمن 1389, 00:43 صبح
ببخشید جناب تاجیک امکان داره در مورد فانکشن SetParentwindow توضیح کاملتری بدین که کارش دقیق چیه و این Mode چی هست و چیکار میکنه و وجودش آیا تو پلاگین الزامیه ؟
برای ترسیم فرم پلاگین تو بخش Design بیلدر ، خود بیلدر ازش استفاده میکنه ؛ اگر پلاگینتون فرم نداره میتوندی حذفش کنید ولی اگر فرم داره اون کد باعث ترسیم اون فرم میشه .


و من وقتی سورس پلاگین های مختلف رو نگاه میکنم میبینم همیشه این Uses ها رو بهش دادن که Classes SysUtils, Variants و طبق ساختار جالب دلفی هنگام کمپایل اگه یه Uses یا دستوری کم یا اشتباه باشه خطا میگیره و اجازه کمپایل نمیده و من همیشه هم این Uses ها رو حذف میکنم و میخواهم کمپایل کنم بدون هیچ مشکل یا خطا گیری توسط دلفی کمپایل میشه حالا میخواستم بدونم آیا استفاده از این Uses ها الزامی است و بعد از حذفشون باعث ایجاد اشکالی میشه چون بعد از حذفشون باعث کم شدن حجم محسوس پلاگین میشه
حذفشون مشکلی نداره ، این کتابخانه ها کتابخانه های اصلی هستند که تو بیشتر پروژه ها کاربرد دارن ، برای همین به صورت پیش فرض تو Uses قرار گرفتن ، شما هر کدوم رو که ازش استفاده نمیکنی حذف کن .

loo30fer
پنج شنبه 07 بهمن 1389, 13:34 عصر
من تابع گرفتن حجم فایل رو تو سورس پلاگین جای دادم حالا نمیدونم چطور براش تعریف کنم که آدرس فایل رو از PluginSet بگیره و بعد از گرفتن حجم چطور به PluginGet بده شرمنده اگه امکان داره برام کدش رو ویرایش کنید میدونم که یک مدت باید با دلفی کار کنم و با نحوه کارش آشنا بشم بعد راحت خودم درستش کنم ولی برای یک کارم که پیاده کردن یک الگوریتم هست نیاز به پلاگین دارم و کسی رو هم نتونستم برای ساختش پیدا کنم و فعلا که مشکل من همین قسمته ممنون میشم کمکم کنید با تشکر

unit PluginInterface;

interface

uses Windows, Messages, SysUtils, PluginInfo;

type
TPluginMode = (pmDesigner, pmRuntime);

var
hMMBWindow: Cardinal;
PluginMode: TPluginMode;
AppDir: string;
SR: TSearchRec;

TextInput: array [1..5] of string;
TextOutput: string;
NumInput: array [1..5] of Integer;
NumOutput: Integer;

EventKeys: string;

implementation

function Copyright: pChar; cdecl;
begin
Result := pChar(PluginCopyright);
end;

function GetShortInfo: pChar; cdecl;
begin
Result := pChar(PluginShortInformation);
end;

function GetInfo: pChar; cdecl;
begin
Result := pChar(PluginInformation);
end;

function GetType: Integer; cdecl;
begin
Result := 0;
end;

procedure SetPath(sPath: pChar); cdecl;
begin
AppDir := sPath;
end;

procedure SetFile(s: pChar); cdecl;
begin
TextInput[5] := TextInput[4];
TextInput[4] := TextInput[3];
TextInput[3] := TextInput[2];
TextInput[2] := TextInput[1];
TextInput[1] := s;
end;

function GetFile: pChar; cdecl;
begin
Result := pChar(TextOutput);
end;

procedure SetData(nData: Integer); cdecl;
begin
NumInput[5] := NumInput[4];
NumInput[4] := NumInput[3];
NumInput[3] := NumInput[2];
NumInput[2] := NumInput[1];
NumInput[1] := nData;
end;

function GetData: Integer; cdecl;
begin
Result := NumOutput;
end;

function MyFileSize(const FileName: String): Int64; cdecl;
begin
if FindFirst(FileName, faAnyFile, SR)=0 then
repeat
Result:= SR.Size;
until (FindNext(SR)<> 0);
FindClose(SR);
end;


exports
Copyright,
GetShortInfo,
GetInfo,
GetType,
SetPath,
SetFile,
GetFile,
SetData,
GetData,
MyFileSize;

end.

Felony
جمعه 08 بهمن 1389, 13:51 عصر
من تابع گرفتن حجم فایل رو تو سورس پلاگین جای دادم حالا نمیدونم چطور براش تعریف کنم که آدرس فایل رو از PluginSet بگیره و بعد از گرفتن حجم چطور به PluginGet بده شرمنده اگه امکان داره برام کدش رو ویرایش کنید میدونم که یک مدت باید با دلفی کار کنم و با نحوه کارش آشنا بشم بعد راحت خودم درستش کنم ولی برای یک کارم که پیاده کردن یک الگوریتم هست نیاز به پلاگین دارم و کسی رو هم نتونستم برای ساختش پیدا کنم و فعلا که مشکل من همین قسمته ممنون میشم کمکم کنید با تشکر
اون کار درست نیست ؛ نباید تو SDK چیزی بنویسید ، اون کتابخانه به عنوان رابط شما عمل میکنه نه فایل پلاگینتون و نگهدارنده سورستون ، دقیقا مثل کتابخانه های دیگه دلفی ؛ مثلا شما میخوای کد بنویسی میری تو کتابخانه Windows کد مینویسی ؟

در ضمن بهتون گفتم توسط TextInput و TextOutput متن میفرستی و میگیری و توسط NumInput و NumOutput عدد .

یه پروژه DLL ایجاد میکنی و به لیست Uses هاش PluginInterface رو اضافه میکنی ، پروژه رو ذخیره میکنی و کتابخانه PuginInterface.pas رو هم کنارش میزاری ؛ حالا تو همون فایل DPR که ساختی کدهات رو مینویسی .

loo30fer
سه شنبه 17 اسفند 1389, 17:18 عصر
سلام
ببخشید من وقتی برای پلاگین این procedure رو تعریف میکنم و کدش رو خالی میذارم به این شکل :
procedure DeleteFile; cdecl;
begin
end;
مشکلی نیست و کمپایل میکنه ولی وقتی از دستورات خود دلفی استفاده میکنم که با نام procedure همنام هست خطا میگیره و اجازه کمپایل نمیده مثل این کد :
procedure DeleteFile; cdecl;
begin
if DeleteFile('') then
end;
چون اگه بخوام اسم Prodecure رو مثلا به DeleteFileX تغییر بدم زیاد جالب نمیشه , برای این مشکل راه حلی وجود داره یا ساختار دلفی اینطوریه و کاریش نمیشه کرد ؟

loo30fer
سه شنبه 17 اسفند 1389, 17:39 عصر
ببخشید یک سوال دیگه هم داشتم
فرض کنید کاربر در MMB دو ScriptTimer ایجاد کرده که هر کدام به طور مداوم هر یک میلی ثانیه یک ورودی رو به پلاگین من میفرستن و فانکشنی رو اجرا میکنن خوب مسلما این فانکشنها همون ابتدای کار اون ورودی رو میگیرن و کار مورد نظر رو انجام میدن حالا وقتی در این تایمرها در اختلاف یک میلی ثانیه ورودی رو میفرستن و فانکشن مورد نظرشون رو اجرا میکنن امکان اینکه تداخلی پیش بیاد و فانکشن FiletSize به جای اینکه ورودی خودش رو که برای مثال C:\File.exe بوده رو ورودی فانکشن FileExists بگیره که D:\File.exe و عملیات اشتباه رو انجام بده هست درسته ؟
آیا برای رفع امکان اتفاق این مشکل تعریف کردن آرایه برای ورودی ها مثل SDK شما این مشکل رو حل میکنه اگه اینطوره ممنون میشم توضیحی در این رابطه بدین که چرا ؟

loo30fer
یک شنبه 22 اسفند 1389, 02:51 صبح
همچنان منتظر جواب :ناراحت: !!!!!

Felony
یک شنبه 22 اسفند 1389, 10:22 صبح
سلام
ببخشید من وقتی برای پلاگین این procedure رو تعریف میکنم و کدش رو خالی میذارم به این شکل :
procedure DeleteFile; cdecl;
begin
end;
مشکلی نیست و کمپایل میکنه ولی وقتی از دستورات خود دلفی استفاده میکنم که با نام procedure همنام هست خطا میگیره و اجازه کمپایل نمیده مثل این کد :
procedure DeleteFile; cdecl;
begin
if DeleteFile('') then
end;
چون اگه بخوام اسم Prodecure رو مثلا به DeleteFileX تغییر بدم زیاد جالب نمیشه , برای این مشکل راه حلی وجود داره یا ساختار دلفی اینطوریه و کاریش نمیشه کرد ؟
طبیعی هست شما نام روال رو DeleteFile قرار دادی بعد از تابعی با همون نام استفاده کردی ، Parser بنده خدا نمیتونه این موضوع رو تحلیل کنه ، باید نام روال رو تغییر بدید .


ببخشید یک سوال دیگه هم داشتم
فرض کنید کاربر در MMB دو ScriptTimer ایجاد کرده که هر کدام به طور مداوم هر یک میلی ثانیه یک ورودی رو به پلاگین من میفرستن و فانکشنی رو اجرا میکنن خوب مسلما این فانکشنها همون ابتدای کار اون ورودی رو میگیرن و کار مورد نظر رو انجام میدن حالا وقتی در این تایمرها در اختلاف یک میلی ثانیه ورودی رو میفرستن و فانکشن مورد نظرشون رو اجرا میکنن امکان اینکه تداخلی پیش بیاد و فانکشن FiletSize به جای اینکه ورودی خودش رو که برای مثال C:\File.exe بوده رو ورودی فانکشن FileExists بگیره که D:\File.exe و عملیات اشتباه رو انجام بده هست درسته ؟
آیا برای رفع امکان اتفاق این مشکل تعریف کردن آرایه برای ورودی ها مثل SDK شما این مشکل رو حل میکنه اگه اینطوره ممنون میشم توضیحی در این رابطه بدین که چرا ؟
بله امکان اشتباه هست ، SDK هم یک رابط هست وقرار نیست معجزه بکنه ، این وظیفه شما هست که این مشکل رو بر طرف کنید .

- برای حل مشکل میتونید یک StringList تعریف کنید و درخواست هایی که به DLL میرسه رو داخل StringList ذخیره کنید و DLL در عین حال دستورات رو از داخل StringList بخونه و بهشون رسیدگی کنه و جواب مرتبط را به برنامه برگردونه ، مثلا برنامه شما هر چند میلی ثانیه اسم یک فایل رو برای به دست آوردن حجم به پلاگین میفرسته ، شما اسم فایل رو به صورت زیر در StringList ذخیره میکنید :


D:\aFile.txt|FileSize

حالا تو یک تایمر یا Thread در DLL شروع میکنید از اول StringList میخونید و اسم فایل و کاری که باید روش انجام بشه رو استخراج میکنید و عملیات رو انجام میدید و به صورت زیر به بیلدر بر میگردونید :


D:\aFile.txt|174

حالا برنامه مقصد هم اسم فایل و هم حجم فایل رو داره و نه مشکلی پیش میاد چون اسم فایل ها داخل صف در StringList هستند و حتما بهشون رسیدگی میشه ، یادتون نره بعد از خوندن و انجام کار از stringList آیتمی که کارش تموم شده رو حذف کنید .

loo30fer
پنج شنبه 26 خرداد 1390, 17:44 عصر
جناب تاجیک من اگه بخوام تو پلاگینم که فرمی نداره از کامپوننت استفاده کنم چطور باید اینکار رو بکنم؟؟؟
چون مانند کدی که گذاشتم حتما باید کامپوننت IdMessage باشه کتابخانه مربوطشم رو به Uses اضافه کردم ولی فایده نداره خطا میگیره. با تشکر.
procedure SendMail; cdecl;
begin
with IdMessage1 do
begin

Felony
جمعه 27 خرداد 1390, 13:05 عصر
الان با این توضیحات توقع چه راهنمایی دارید ؟ چی کار کردید که خطا میده ؟ چه خطایی میده ؟
IDMessage1 رو قبل از استفاده نمونه سازی کردید ؟
بهترین راه استفاده از یک Data Module هست .

loo30fer
جمعه 27 خرداد 1390, 13:46 عصر
الان با این توضیحات توقع چه راهنمایی دارید ؟ چی کار کردید که خطا میده ؟ چه خطایی میده ؟
خوب از اینکه این توضیحات کامل رو دادین ممنون ولی من برای استفاده از کامپوننت تو پلاگینم نتونستم از هیچ کدوم راهنمایی شما استفاده و به کار بگیرم.

IDMessage1 رو قبل از استفاده نمونه سازی کردید ؟
نه راستش مشکل منم همینه که چطوری ایجادش کنم.

بهترین راه استفاده از یک Data Module هست .
میشه در این مورد یکم توضیح بدین که چی هست و چطور کار میکنه یا حداقل یک منبع رو برای من برای فهم این موضوع معرفی کنید ممنون.

Felony
جمعه 27 خرداد 1390, 18:03 عصر
نه راستش مشکل منم همینه که چطوری ایجادش کنم.
خسته نباشید ؛ برای اینکه شروع به کار با اشیاء در DLL ها کنید باید با نحوه نمونه سازی اشیاء و مدیریت حافظه اونها به صورت Runtime آشنایی کامل داشته باشید .


میشه در این مورد یکم توضیح بدین که چی هست و چطور کار میکنه
Data Module تقریبا شبیه یک فرم هست که قابلیت بصری در Runtime نداره ، یعنی در هنگام اجرا چیزی به شما نمایش نمیده ، پس شما نمیتونید روی اون از اشیاء Visual مثل Button , ComboBox, ListBox و ... استفاده کنید ولی در عوض میتونید از اشیاء Non Visual مثل Timer, ADO, Indy و ... استفاده کنید .

با استفاده از Data Module نیازی نیست که شیئ رو هر بار که بهش نیاز دارید Create کنید و در این میان نگران از دست رفتن اطلاعات یا مدیریت حافظش باشید ، کافیه در Entry Point پروژه DLL تون در هنگام بار شدن DLL شئ Data Module رو Create کنید و در هنگام Unload شدن آزادش کنید ، Data Module هم وظیفه مدیریت حافظه اختصاصی به اشیاء قرار گرفته بر روی خودش رو مثل فرم معمولی بر عهده میگیره .

یک نمونه پلاگین براتون نوشتم و ضمیمه کردم .

loo30fer
سه شنبه 28 تیر 1390, 00:26 صبح
سلام
جناب تاجیک من میتونم هندل فرم رو با توجه به تابع SetParentWindow که تو SDK تعریف شده بگیرم که مانند Form1.Handle عمل میکنه ولی اگه بخوام هندل خود برنامه رو بگیرم مانند Application.Handle چیکار باید بکنم ؟ ممنون میشم راهنمایی کنید. با تشکر

Felony
سه شنبه 28 تیر 1390, 07:56 صبح
ولی اگه بخوام هندل خود برنامه رو بگیرم مانند Application.Handle چیکار باید بکنم ؟
Application.Handle در هیچ جا به جز Delphi معنا نداره ، در زمان طراحیDelphi گروه توسعه دهنده برای پیاده سازی یکسری از امکانات مجبور شدن Delphi رو طوری پیاده سازی کنن که یک فرم مخفی داشته باشه ( Application ) که والد فرم های دیگر برنامه هست و یکسری از عملیات های مدیریتی رو در پشت صحنه انجام میده .

به خودی خود یک Application ( منظور برنامه ) هندلی مثل Application.Handle در Delphi نداره ، حالا شما دقیق بگو چی کار میخوای بکنی ...

loo30fer
سه شنبه 28 تیر 1390, 12:49 عصر
Application.Handle در هیچ جا به جز Delphi معنا نداره ، در زمان طراحیDelphi گروه توسعه دهنده برای پیاده سازی یکسری از امکانات مجبور شدن Delphi رو طوری پیاده سازی کنن که یک فرم مخفی داشته باشه ( Application ) که والد فرم های دیگر برنامه هست و یکسری از عملیات های مدیریتی رو در پشت صحنه انجام میده .

به خودی خود یک Application ( منظور برنامه ) هندلی مثل Application.Handle در Delphi نداره
بسیار بسیار ممنون از توضیحاتتون و اینکه همیشه جواب سوالات من رو میدین.

حالا شما دقیق بگو چی کار میخوای بکنی ...
راستش من میخوام آیکون برنامه های بیلدر رو از Taskbar مخفی کنم و از این تابع ShowWindow هم استفاده کردم ولی به جای اینکه ایکونش از تسکبار مخفی بشه کل پروژه مخفی میشد بعد که دقیق بهش توجه کردم فهمیدم من دارم هندل فرم رو بهش میدم نه مثل دلفی هندل برنامه برای همین هم هست که کل فرم مخفی میشه برای همین هم همین سوال رو پرسیدم. اتفاقا یک پلاگین در این رابطه براش وجود داره برای من سوال شده اون از چه روشی استفاده کرده ؟؟
یک سوال دیگر من وقتی تو پلاگین از تابع SendMessage استفاده میکنم تا مثلا یک دستور یا اسکریپت رو تو برنامه اجرا کنم چون توسط برنامه این پلاگین لود میشه این تابع بدرستی کار میکنه و مثلا گفتم اسکریپت رو اجرا کنه که میکنه ولی اگه من این پلاگین رو تو برنامه دیگه لود کنم و بخوام یک اسکریپت رو تو برنامه دیگر که البته هردو با بیلدر ساخته شده هستن اجرا کنم کار نمیکنه البته من هندل اون برنامه رو بدست میارم و به پلاگین میدم ولی کار نمیکنه یکجورایی مثل این میمونه که بیلدر اجازه چنین دسترسی رو به غیر از برنامه خودش نمیده فکر میکنم برای همین هم هست که اجازه ارسال اون مقدار رو به برنامش برای اجرای اسکریپت نمیده , نظر شما چیه دلیل اینکه نمیشه چیه ؟ با تشکر

ansoft
چهارشنبه 02 آذر 1390, 16:45 عصر
سلام
آقاي تاجيك با چه كدي ميشه كه پلاگين متن هايي كه از mmb گرفته رو بتونه اينطوري بخونه:
كد mmb
set$='Title|Text|btn|checkbox'
PluginSet("Plugin","set$")
PluginRun("Plugin","MessageBox")


با اين كد همه متن هايي كه به پلاگين ارسال ميشه را در يك بار ارسال به پلاگين ميده و ديگه نميخواد براي هر يك از واژه ها يك ارسالي به پلاگين داشته باشيم.

حالا من ميخوام بدانم كه در دلفي در قسمت messagebox چه كدي بنويسم كه اينها را دريافت كنه؟
لطفا كمي توضيح بديد تا اگر خواستم تعداد set$=Title|Text|btn|checkbox را زياد كنم بتونم.
با تشكر

javad p
چهارشنبه 02 آذر 1390, 18:03 عصر
این نمونه کد کمکتون میکنه



var
t1:string;
t2:array[1..10] of string;
i,j:Integer;
begin
t1:=g_String;
j:=1;
for i:=1 to Length(t1) do
begin
if t1[i]='|' then
begin
j:=j+1;
end
else
t2[j]:=t2[j]+t1[i];
end;


g_String همون set$ هست که پلاگین دریافت میکنه که شما باید با ورودی پلاگینتوم تغییرش بدید
10 هم تعداد تکه هایی هست که براتون میتونه جدا کنه
موفق باشید

loo30fer
چهارشنبه 02 آذر 1390, 19:28 عصر
قبلا یک تابع مانند GetArrayItem بیلدر نوشته بودم براتون میذارم:
function GetArrayItem(const TextIn: String; Car: PChar; const offset: Integer) : String;
var
i,srch: Integer;
begin
for i:=0 to offset do begin
if (i<>offset) then
srch:= PosEx(Car, TextIn+Car,srch+1);
end;
Result:= Copy(TextIn,srch+1,PosEx(Car, TextIn+Car,srch+1)-srch-1);
end;
و نحوه استفاده :
GetArrayItem(TextInput,'|',1)

ansoft
سه شنبه 08 آذر 1390, 17:21 عصر
تشکر
آقای لوسیفر اگه امکان داره بک نمونه مثال کامل با دلفی 7 برام بنویسید . اینجوری نفهمیدم
-
یک سوال دیگه .
چگونه در mmb با پلاگین یک شیء بسازم .
مثلا برای ساخت یک دکمه برنامه عنوان ، موقعیت و ... را دریافت کنه و یک دکمه در mmb بسازه؟

loo30fer
سه شنبه 08 آذر 1390, 20:28 عصر
یک نمونه براتون پیوست کردم.

چگونه در mmb با پلاگین یک شیء بسازم .برای ساخت اشیا بدون استفاده از فرم میتونید بدین شکل عمل کنید برای اینکه وقتی از کتابخانه فرم استفاده میکنید پلاگینتون حجم زیادی رو پیدا میکنه.
این hMMBWindow هم متغیر که حاوی هندل پنجره ای است که از پلاگین استفاده میکنه اگه متوجه نشدین یک نگاهی به SDK که جناب تاجیک ضمیمه کردن بندازین و کدها رو بررسی کنید همه چیز دستگیرتون میشه.

var
Button: TButton;
begin
Button:= TButton.Create(nil);
Button.ParentWindow:= hMMBWindow;
end;

موفق باشید.

javad p
چهارشنبه 09 آذر 1390, 15:20 عصر
شما با توجه به تازه کار بودنت سخته برات که از کد Button.Create(nil); برای ساخت دکمه استفاده کنی
مخصوصا برای دستور دادن به اون برای بعد
یه دکمه رو فرمت بزار و اونو با پلاگین show و hide کن

arash-mmb
چهارشنبه 02 مرداد 1392, 11:27 صبح
با سلام

من آخرش ندونستم اگه همه اینا رو تو دلفی می نویسی ، چطور باید به فایل Dll تبیدلشون کنید؟

firststep
چهارشنبه 02 مرداد 1392, 13:39 عصر
سلام
اموزش های اقای عشایری منبع خوبی برای ساخت dll هست
می تونین جستجو کنین

BORHAN TEC
چهارشنبه 02 مرداد 1392, 15:02 عصر
سلام

سلام
اموزش های اقای عشایری منبع خوبی برای ساخت dll هست
می تونین جستجو کنین
به این لینک مراجعه کنید:
http://www.irstu.com/?p=8490
در 5 درس آخر نحوه ساخت و استفاده از dll ها را توضیح داده ام.
موفق باشید...