نقل قول نوشته شده توسط 1485159 مشاهده تاپیک
ممنون
فقط اگه به من بگید که چطور با برنامه ام به برنامه دیگه ای مثلا پیامی بفرستیم با متن:ali
و با اونیکی چطور بفهمیم که بیامی به برنامه ما فرستاده شده یا نه!؟..
ممنون.
نقل قول نوشته شده توسط 1485159 مشاهده تاپیک
کسی نیست جواب بده!؟..
نقل قول نوشته شده توسط 1485159 مشاهده تاپیک
بابا جان من جواب بدین!!
دلفی رو یدادی نداره که هنگام در یافت پارامتر به ما خبر بد]!؟..
اولا همیشه همینطوری نیست که شما یه پست بدی، بچه ها 2 دقیقه بعد باید جوابتو بدن! یکمی زحمت بکش جستجو کن ببین جاهای دیگه چی گفتن، تو خود سایت در این مورد (که بنده دو تا سرنخ بهتون دادم تو پست قبلی ام) نکات متنوعی مطح شده که شما نگشتین؛ اگه هم فکر میکنی مطلبی نیست! یه مقدار صبر باید بکنی، و پست اضافی ندی، سنگک پزی نیست!

ثانیا : تا اونجاییکه من میدونم همچین رویدادی تو دلفی نداریم، برای اینکار چون با این پستها میشه فهمید که آدم صبوری نیستین، من راه اول رو واستون باز میکنم (راه دوم پیچیده تر هست و با روحیه شما جور در نمیاد)

شما برای اینکار باید از روالهای ارسال پیام خود ویندوز استفاده کنید؛ توضیحات مفصلی در مورد این مباحث وجود داره که میتونید از MSDN و تاپیکهای مختلف یاست درمورد اونا کسب اطلاع کنید، بنده با فرض اطلاع شما از نحوه عملکرد پیامهای ویندوز، راه حل رو ارائه میدم :

  1. قبل همه شما باید یه ثابتی برای ارتباط بین برنامه ها داشته باشید که با شماره پیامهای ویندوز قاطی نشه :
    const
    WMU_OUT_MESSAGE = WM_USER + 1;
  2. عمل بعدی ایجاد همون رویدادی هست که شما می خواستید، یعنی جایی که به این درخواست رسیدگی بشه، برای اینکار شما باید یه windows procedure بنویسین، تا اگه پیغام رسیده، همونی بود که شما میخواستین، بهش رسیدگی بشه و درغیر اینصورت روال ویندوزی در مورد اون پیگیری بشه، با حدس من در مورد کارکرد برنامه شما، مثلا یه همچین procedure ای میشه :

    (*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)

    // in TForm1 public section
    procedure MyWndProc(var wndMsg: TMessage); override;

    (*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)

    procedure TForm1.MyWndProc(var wndMsg: TMessage);
    var
    p: PChar;
    begin
    try
    case wndMsg.Msg of

    WMU_OUT_MESSAGE:begin
    p := PChar(wndMsg.WParam);
    if p <> nil then begin
    Memo1.Lines.Add(p);
    FreeMem(p);
    end;
    end;

    else inherited;
    end;
    except on exp:Exception do
    Memo1.Lines.Add('Exception on MyWndProc['+IntToStr(wndMsg.Msg)+']: '+exp.Message);
    end;
    end;

    (*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)
    ضمنا با این روال، شما یکی از پارامترهایی که میتونستین استفاده کنید یعنی LParam رو فعلا استفاده نکردید، به این ترتیب بعدا در صورت گسترش برنامه میتونین از اون هم برای کارهای دیگه (مثلا نحوه نمایش متن موردنظر) استفاده کنید و ...
  3. قسمت آخر فرستادن پیام از یه برنامه دیگه به این برنامه است؛ برای اینکار همونطوریکه در بند قبل دیدین، باید آدرس رشته موردنظر رو به برنامه سرور بدین؛ برای اینکار من از رشته مورد نظر یه instance تو RAM درست میکنم و اون آدرس رو به روال هندل پیام که تو بند قبل نوشتیم میدم :
              
    (*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)

    procedure SendMyMessage(wHnd: THandle; mess: string);
    var
    function strdup(s: string): PChar;
    begin
    Result := AllocMem(Length(s) + 1);
    StrPCopy(Result, s);
    end;
    begin
    // wHnd is your server handle
    PostMessage(wHnd, TH_EVENT_OUT_MESSAGE, WPARAM(strdup(mess)), 0);
    end;

    (*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)

    البته باید توجه کنید که برای استفاده از این تابع باید هندل سرور رو داشته باشید، که روش اینکار درصورت جستجو همه جا هست، برای نمونه هم تو سایت Torry میتونید یه نمونه اش رو پیدا کنید، ولی با فرض اینکه شما یه instance از سرورتون دارین میتونید از یکی از توابع زیر برای اینکار استفاده کنید (توجه کنید که تابع اول برای موقعی هست که سرور تو یه ماشین دیگه اس ...) :

    (*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)

    function GetPid(sService: String; sMachine: String = '') : Cardinal;
    var
    schm,
    schs: SC_Handle;
    SC_STATUS_TYPE: Cardinal;
    lpBuffer: _SERVICE_STATUS_PROCESS;
    cbBufSize: DWORD;
    pcbBytesNeeded: LPDWORD;
    begin
    //open the service manager (defined in WinSvc)
    schm := OpenSCManager(PChar(sMachine), nil, SC_MANAGER_CONNECT);
    //set the status type to SC_STATUS_PROCESS_INFO
    //this is currently the only value supported
    SC_STATUS_TYPE := $00000000;
    //set the buffer size to the size of the record
    cbBufSize := sizeof(_SERVICE_STATUS_PROCESS);
    if (schm>0) then
    begin
    //grab the service handle
    schs := OpenService(schm, PChar(sService), SERVICE_QUERY_STATUS);
    if (schs>0) then
    begin
    //call the function
    QueryServiceStatusEx(
    schs,
    SC_STATUS_TYPE,
    lpBuffer,
    cbBufSize,
    pcbBytesNeeded);
    CloseServiceHandle(schs);
    end;
    CloseServiceHandle(schm);
    end;
    Result := lpBuffer.dwProcessId;
    end;

    (*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)

    function GetProcessID(ProcessName:string):Integer;
    var
    Handle:tHandle;
    Process:tProcessEntry32;
    GotProcess:Boolean;
    begin
    Handle:=CreateToolHelp32SnapShot(TH32CS_SNAPALL,0) ;
    Process.dwSize:=SizeOf(Process);
    GotProcess := Process32First(Handle,Process);
    {$B-}
    if GotProcess and (Process.szExeFile<>ProcessName) then
    repeat
    GotProcess := Process32Next(Handle,Process);
    until (not GotProcess) or (Process.szExeFile=ProcessName);
    {$B+}
    if GotProcess then Result := Process.th32ProcessID
    else Result := 0;
    CloseHandle(Handle);
    end;

    (*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*)

  4. در نهایت شما فقط لازمه که مثلا
    SendMyMessage(GetProcessID('MyServer'), 'ali');
    رو فراخوانی کنید.

پ.ن. : باید بدونین که این همه اون چیزی نیست که لازمه واسه اینکار بدونین، میشه از روشهای دیگه ای مثل socket یا pipe و ... هم استفاده کرد که با پورت خاصی اطلاعات بین پروسسهای شما رد و بدل میشه و هرکدوم مزایای خودشون رو دارن (این به نظر من ساده ترین راه بود) ...