Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Взаимодействие приложений. Какой механизм лучше? 
:(
    Опции темы
Bes
Дата 25.2.2005, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 806
Регистрация: 8.12.2004

Репутация: 5
Всего: 7



Вообщем проблема такая. У меня есть много разных приложений которые выполняют много разных задач. Они могут быть на разных машинах, их может быть запущено несколько экземпляров. И некоторые из них должны общаться с некоторыми из них.
Расскажите как вы решаете проблемы с взаимодецствием приложений?
Какой механизм лучше?
Если хотите рассказать про ДДЕ, топриведите кусок РАБОТАЮЩЕГО кода, поскольку сколько я не бился над освоением этой технологии, так у меня ничего и не вышло.
DRKB смотрел - бесполезно, не компилируется.
По описаниям делал - компилируется, но передачи нет.

Кстати Vit-у, в дркб очень много примеров которые не работают видимо не потому что они не работают, а потому что нужно догадываться, что для этой ф-ии нужен модуль ШеллАПИ или Хелп32, а скажем здесь нужно Кардинал на Интеджер поменять вследствие различия версий дельфи, а некоторые я так и не разгадал :-) в том числе и ДДЕ.
Т.е. надо бы это... да. Вот. ну спасибо заранее.
PM MAIL   Вверх
Dimich
Дата 25.2.2005, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 247
Регистрация: 25.8.2004
Где: Брянск

Репутация: 1
Всего: 7



Похожую проблему пытаюсь и я сейчас решить. До финальной реализации дела еще не дошли, но передачу информации я пытаюсь сделать через MailSlot'ы. Для моих задач это вполне приемлимо, а как получится на практике - пока не знаю, но думаю: куда оно денется!
--------------------
Не работает - исправь, работает - не трогай!!!
PM MAIL ICQ Jabber   Вверх
z-END
Дата 25.2.2005, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: 11
Всего: 102



раз идет разговор о том что программы могут находится на разных машинах, то DDE тебя и не спасет, выход использовать сокеты или тсп, залазь в раздел Delphi сети и смотри там различные вопросы то ServerSocket, TCP и тому подобным


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Александра
Дата 25.2.2005, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 219
Регистрация: 20.2.2005
Где: Москва

Репутация: 7
Всего: 12



или еще лучше MailSlots
--------------------
PM   Вверх
bursa
Дата 25.2.2005, 14:42 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Используй RPC.

Сделать свой прогу OLE-сервером не очень сложно. Одновременно получаешь возможность пользоваться своей прогой из любого приложения, хоть из ворда, хоть из 1с

Лично у меня так и организовано, и стабильно работает, в том числе и по удаленному доступу.
  Вверх
Bes
Дата 25.2.2005, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 806
Регистрация: 8.12.2004

Репутация: 5
Всего: 7



Димыч, спасибо буду ждать твоего релиза... :-)

2bursa: А чуть по-подробнее можно? Что это такое RPC? В каком направлении рыть?

2z-END: А если на локальном компе, то как быть с портами для сокетов их надо как-то разделять.... Вопрос.

2Александра: "Эти глаза напротив... " :-) (надо себе че-нить подобное прилепить) А можно поподробнее про мЭйл-слоты?
PM MAIL   Вверх
Александра
Дата 25.2.2005, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 219
Регистрация: 20.2.2005
Где: Москва

Репутация: 7
Всего: 12



Bes
smile

ну это штука такая, грубо говоря файл )) создается ф-ей CreateMailslot. просто зайди в справку в дельфе по Win32 SDK, там все описано.
--------------------
PM   Вверх
maxim1000
Дата 25.2.2005, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник
Сообщений: 3334
Регистрация: 11.1.2003
Где: Киев

Репутация: 4
Всего: 110



от себя еще могу добавить Pipes (тоже довольно удобно)
а вообще, все это - возможности системы, и лучше всего будет заглянуть в MSDN
там, правда, все на C, но в принципе все основывается на вызове API-шных функций с нужными параметрами в нужной последовательности smile
другое дело, если использовать какие-то компоненты для этого - тут я уж ничем помочь не смогу...
Добавлено @ 15:37
pipes и mailslotes также хороши тем, что они делают прозрачной связь между компьютерами в LAN: можно все отладить на одном компьютере, а потмо запустить на разных и подправить имена (например: .\\pipe\qqq на compname\\pipe\qqq)

Это сообщение отредактировал(а) maxim1000 - 25.2.2005, 15:38


--------------------
qqq
PM WWW   Вверх
Dimich
Дата 25.2.2005, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 247
Регистрация: 25.8.2004
Где: Брянск

Репутация: 1
Всего: 7



Могу дать пример модуля (доработаешь по своему желанию и требованиям), который организует общение посредством MailStot'ов. Авторство в основном не мое - кажется содрал откуда-то вроде delphiworld.ru Сам просто немного туда дописал и изменил. Но учтите, что модуль в стадии дописывания, поэтому принимайте как есть. Это, чтобы разобраться, с чем эти мейлслоты едят...
Код
unit uMessages;

interface
Uses
 Types;
Type
 tMessage = record
   Sender,         // отправитель
   Recip,          // получатель
   Mess : string;  // сообщение
 end;

function SendMessage (ToComputer, Msg : String) : boolean;
function ReadMessage (NextMsgSize : DWord) : tMessage;
function GetComputerName : String;
function InitMailSlots : boolean;
procedure ClearMailSlot;
function ReadMsg : tMessage;
function ExistMessages : boolean;

var
 MailslotHandle:Word;
 MSlotName:String;
 ComputerName:String;

implementation
Uses
 Windows, SysUtils;
function SendMessage(ToComputer, Msg:string): boolean;
var
  hToSlot:THandle;
  BytesWritten:DWord;
  FullSlot,
  Data:String;
  SendMsg:string;
begin
  Result := false;
  SendMsg := Copy (Msg, 1, Length (Msg));
  CharToOEM(PChar(SendMsg), PChar(SendMsg)); // необходимо чтобы поняли по pyсски.
  Data:=ComputerName+#0+ToComputer+#0+SendMsg; // собирам сообщение для отправки

  FullSlot:='\\'+ToComputer+'\mailslot\'+MSlotName; // собираем имя mailslot'а
  hToSlot:=CreateFile(PChar(FullSlot), // создаём файл, для записи данных
    GENERIC_WRITE,
    FILE_SHARE_READ,
    NIL,
    CREATE_ALWAYS,
    FILE_ATTRIBUTE_NORMAL,
    0);

  if hToSlot<>INVALID_HANDLE_VALUE then
  begin
    BytesWritten:=0;
    If (NOT
      WriteFile(hToSlot,
      Pointer(Data)^,
      Length(Data),
      BytesWritten,
      NIL)) OR
      (BytesWritten <> Length(Data)) then Result:=false Else Result:=true;
      // если не удалось записать данные или размер записанных данных
      // и данных подготовленых для отправки не совпадает то вернуть ложное значение.
  end; // hToSlot<>INVALID_HANDLE_VALUE
end; { SendMessage }

function ReadMessage(NextMsgSize:DWord) : tMessage;
var
  Newline,Sender,Recip,Msg:String;
  MsgSize:DWord;
begin
  SetLength(NewLine,NextMsgSize);
  ReadFile(MailslotHandle, PChar(NewLine)^, NextMsgSize, MsgSize, nil);
  Sender:=AnsiUpperCase (Copy(newline,1,pos(chr(0),newline)-1));
  Delete(newline,1,Pos(chr(0),newline));
  // определение получателя
  Recip:=AnsiUpperCase (Copy(newline,1,pos(chr(0),newline)-1));
  Delete(newline,1,Pos(chr(0),newline));
  // всё что осталось - сообщение
  Msg:=Trim(TrimRight(newline));
  OEMToChar(PChar(Msg),PChar(Msg)); // чтобы понять pyсские символы.
  Result.Sender := Sender;
  Result.Recip := Recip;
  Result.Mess := Msg;
end; { ReadMessage }

function GetComputerName:String;
var
  N: Cardinal;
  Buf: array [0..MAX_COMPUTERNAME_LENGTH + 1] of AnsiChar;
begin
  N:=SizeOf(Buf)-1;
  Windows.GetComputerName(Buf, N);
  Result:=PChar(@Buf[0]);
end; { GetComputerName }

function InitMailSlots : boolean;
var
 MSlotCreate:String;
 Error:Dword;
begin
 ComputerName := Uppercase(GetComputerName);
 MSlotName := 'shellmsg'; // messngr - майлслот службы сообщений.
 MSlotCreate:='\\.\mailslot\'+MSlotName;
 MailslotHandle := 0;
 Error := 0;
 SetLastError (0);
 MailslotHandle := CreateMailSlot(PChar(MSlotCreate),
                                  0,
                                  MAILSLOT_WAIT_FOREVER,
                                  nil);
 Error := GetLastError();
 Result := not ((Error<>0) or (MailslotHandle=0) or (MailslotHandle=INVALID_HANDLE_VALUE));
end; { InitMailSlots }

procedure ClearMailSlot;
var
  NextMsgSize,
  MsgSize,
  MsgCount:DWord;
  NewLine:String;
  DummyBuffer:Char;
begin
  NextMsgSize:=0;
  MsgSize:=0;
  GetMailSlotInfo(MailslotHandle, NIL, NextMsgSize, @MsgCount, NIL);
  While NextMsgSize<>MAILSLOT_NO_MESSAGE do
  begin
    if NextMsgSize>5 then ReadMessage(NextMsgSize)
    // по формату сообщение не может быть меньше 5 символов, даже от компьютера,
    // чьё имя состоит из одной буквы.
    Else ReadFile(MailslotHandle, DummyBuffer, NextMsgSize, MsgSize, nil);
    // считываем в ненужный буфер чтобы сообщение не лежало в слоте.
  end;
end; { ClearMailSlot }

function ReadMsg : tMessage;
var
  NextMsgSize,
  MsgSize,
  MsgCount:DWord;
  NewLine:String;
  DummyBuffer:Char;
begin
  NextMsgSize:=0;
  MsgSize:=0;
  Result.Sender := '';
  Result.Recip := '';
  Result.Mess := '';
  GetMailSlotInfo(MailslotHandle, NIL, NextMsgSize, @MsgCount, NIL);
  if NextMsgSize<>MAILSLOT_NO_MESSAGE then
  begin
    if NextMsgSize>5 then Result := ReadMessage(NextMsgSize)
    else ReadFile(MailslotHandle, DummyBuffer, NextMsgSize, MsgSize, nil);
  end;
end; { ReadMsg }

function ExistMessages : boolean;
var
  NextMsgSize,
  MsgSize,
  MsgCount:DWord;
  NewLine:String;
  DummyBuffer:Char;
begin
  NextMsgSize:=0;
  MsgSize:=0;
  GetMailSlotInfo(MailslotHandle, NIL, NextMsgSize, @MsgCount, NIL);
  if not (NextMsgSize = MAILSLOT_NO_MESSAGE) then
  begin
    Result := true;
    if NextMsgSize<5 then
    begin
      ReadFile(MailslotHandle, DummyBuffer, NextMsgSize, MsgSize, nil);
      Result := false;
    end;
  end
  else
  Result := false;
end; { ExistMessages }

end.

--------------------
Не работает - исправь, работает - не трогай!!!
PM MAIL ICQ Jabber   Вверх
bursa
Дата 25.2.2005, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 98
Регистрация: 25.2.2005
Где: Липецк

Репутация: нет
Всего: 1



RPC-удаленный вызов процедур.
В своем проекте File-New-Other-Automation Object

Вот мой пример для Name = NAKLPER


unit Project1_TLB; -формирутся в результате манипуляций мышкой после File-New-Other-Automation Object

Код
// ************************************************************************ //
// WARNING                                                                    
// -------                                                                    
// The types declared in this file were generated from data read from a      
// Type Library. If this type library is explicitly or indirectly (via        
// another type library referring to this type library) re-imported, or the  
// 'Refresh' command of the Type Library Editor activated while editing the  
// Type Library, the contents of this file will be regenerated and all        
// manual modifications will be lost.                                        
// ************************************************************************ //

// PASTLWTR : $Revision:   1.88.1.0.1.0  $
// File generated on 05.04.2002 9:54:16 from Type Library described below.

// ************************************************************************ //
// Type Lib: C:\share\replication2\server.tlb (1)
// IID\LCID: {3FAF4995-DE94-4118-8320-F5AA045B4D71}\0
// Helpfile:
// DepndLst:
//   (1) v2.0 stdole, (C:\WINNT\System32\stdole2.tlb)
//   (2) v4.0 StdVCL, (C:\WINNT\System32\STDVCL40.DLL)
// ************************************************************************ //
{$TYPEDADDRESS OFF} // Unit must be compiled without type-checked pointers.
interface

uses Windows, ActiveX, Classes, Graphics, OleServer, OleCtrls, StdVCL;

const
 // TypeLibrary Major and minor versions
 Project1MajorVersion = 1;
 Project1MinorVersion = 0;

 LIBID_Project1: TGUID = '{3FAF4995-DE94-4118-8320-F5AA045B4D71}';

 IID_Inaklper: TGUID = '{F5378AA8-7547-4A99-B660-1BDD6031E7D3}';
 CLASS_naklper: TGUID = '{73DE164F-C221-4A50-A9E9-CA2F4D427E83}';
type

 Inaklper = interface;

 naklper = Inaklper;


 Inaklper = interface(IUnknown)
   ['{F5378AA8-7547-4A99-B660-1BDD6031E7D3}']
   function  FUNCTION_NAKLPER(s: OleVariant; tablename: OleVariant): HResult; stdcall;
   function  FUNCTION_SPRAV(s: OleVariant; out out_str: OleVariant): HResult; stdcall;
 end;

 Conaklper = class
   class function Create: Inaklper;
   class function CreateRemote(const MachineName: string): Inaklper;
 end;

implementation

uses ComObj;

class function Conaklper.Create: Inaklper;
begin
 Result := CreateComObject(CLASS_naklper) as Inaklper;
end;

class function Conaklper.CreateRemote(const MachineName: string): Inaklper;
begin
 Result := CreateRemoteComObject(MachineName, CLASS_naklper) as Inaklper;
end;

end.




и далее ...

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 Db, DBTables, StdCtrls;

type
 TForm1 = class(TForm)
   QINSNAKLPER: TQuery;
....
   procedure FormClose(Sender: TObject; var Action: TCloseAction);
   procedure FormCreate(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
  function GO_PROC(var Q:TQuery;var word_key:string):boolean;
 end;

var
 Form1: TForm1;

implementation

{$R *.DFM}

function TForm1.GO_PROC(var Q:TQuery; var word_key:string):boolean;
var s:string;
   j:integer;
   f:textFile;
begin
word_key:='';

if not Q.Active then
Q.Open;
if Q.Eof then begin
Q.CLOSE;
word_key:='&&&';
end else begin

for j:=0 to Q.FieldCount-1 do begin
word_key:=word_key+Q.Fields[j].asString+'#';
end;

Q.Next;
end;

end;



procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
QROLLBACK.EXECSQL;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
ShortDateFormat:='dd.mm.yyyy';
end;


end.



и далее...



unit Unit2;

interface

uses
 Windows, ActiveX, Classes, ComObj, Project1_TLB, StdVcl,
 Db, DBTables, StdCtrls;

type
 Tnaklper = class(TTypedComObject, Inaklper)
 protected
   function FUNCTION_NAKLPER(s, tablename: OleVariant): HResult; stdcall;
   function FUNCTION_SPRAV(s: OleVariant; out out_str: OleVariant): HResult;
     stdcall;
   {Declare Inaklper methods here}
 end;

implementation

uses ComServ, unit1;




function Tnaklper.FUNCTION_NAKLPER(s, tablename: OleVariant): HResult; -
VAR S1:CHAR;    
   S2,s_:STRING;
   K,J,J1:INTEGER;
   Q,Q2:TQuery;
   SP:TSToredProc;
   SP_if:boolean;
BEGIN
try
result:=0;
if tablename='QZREP' THEN
FORM1.QZREP.EXECSQL ELSE
if tablename='QCOMMIT' THEN begin
FORM1.QCOMMIT.EXECSQL;
result:=1;
Form1.memo1.Lines.Add('Репликация прошла успешно');
end ELSE
if tablename='QCOMMIT1' THEN begin
FORM1.QCOMMIT.EXECSQL;
result:=1;
end ELSE
if tablename='QROLLBACK' THEN begin
 FORM1.QROLLBACK.EXECSQL;
 Form1.memo1.Lines.Add('Неудачная попытка репликации');
 end ELSE  BEGIN

SP_if:=false;
if tablename='NAKLPER' then
 Q:=FORM1.QINSNAKLPER
else
if tablename='POKUPATEL' then begin
 Q:=FORM1.QINSPOKUPATEL;
 Q2:=FORM1.QUPPOKUPATEL;
end  else
if tablename='PEREMESH' then BEGIN
 Q:=FORM1.QINSPEREMESH;
 SP:=FORM1.SP_POSTPEREMESH;
 SP_if:=true;
END else
if tablename='NAKLRASHOD' then
 Q:=FORM1.QINSNAKLRASHOD
else
if tablename='PRIHOD' then BEGIN
 Q:=FORM1.QINSPRIHOD;
 SP:=FORM1.SP_POSTPRIHOD;
 SP_if:=true;
END else
if tablename='NAKLPRIH' then
 Q:=FORM1.QINSNAKLPRIH
else
if tablename='RASHODPRODANO' then BEGIN
 Q:=FORM1.QINSRASHOD;
 SP:=FORM1.SP_POSTPRODANO;
//  SP_if:=true;
END else
if tablename='RASHODKREDIT' then BEGIN
 Q:=FORM1.QINSRASHOD;
 SP:=FORM1.SP_POSTKREDIT;
 SP_if:=true;
END;

RESULT:=1;
Form1.memo1.Lines.Add(tablename);
s_:=s;
S2:='';
K:=1;
FOR J:=1 TO LENGTH(S_)-1 DO BEGIN
S1:=S_[J];
if s1= ',' then s1 := '.';
IF S1=CHAR(22) THEN BEGIN
Q.PARAMS[K-1].asString:=s2;
Form1.memo1.Lines.Add(s2+' ');
s2:='';
k:=k+1;
if k>Q.ParamCount then begin
k:=1;
//Q.PARAMS[0].asString:=Q.PARAMS[0].asString+'0';
//Q.PARAMS[1].asString:=Q.PARAMS[1].asString+'00';
try


Q.ExecSQL;
except
for j1:=0 to Q.ParamCount-1 do
Q2.Params[j1].asString:=Q.Params[j1].asString;
Q2.ExecSQL;
end;
if SP_if then begin
SP.Params[0].asString:=Q.PARAMS[1].asString;
SP.ExecProc;
end;
end;

END ELSE
S2:=S2+S1;


END;

END;
result:=1;
except
result:=0;
end;
END;

function Tnaklper.FUNCTION_SPRAV(s: OleVariant;
 out out_str: OleVariant): HResult;
var   s1:string;
begin
s1:=s;
if s1='IZM' then
  Form1.GO_PROC(Form1.QIZM,s1) else
if s1='OTDEL' then
  Form1.GO_PROC(Form1.QOTDEL,s1) else
if s1='KATEGORY' then
  Form1.GO_PROC(Form1.QKATEGORY,s1) else
if s1='PROIZVODITEL' then
  Form1.GO_PROC(Form1.QPROIZVODITEL,s1) else
if s1='TOVAR' then
  Form1.GO_PROC(Form1.QTOVAR,s1) else
if s1='KURS' then
  Form1.GO_PROC(Form1.QKURS,s1) else
if s1='PRODAVEZ' then
  Form1.GO_PROC(Form1.QPRODAVEZ,s1) else
if s1='POKUPATEL' then
  Form1.GO_PROC(Form1.QPOKUPATEL,s1) else
if s1='TOVAR_IN_OTDEL' then
  Form1.GO_PROC(Form1.QTOVAR_IN_OTDEL,s1) else
if s1='TOVAR_MINCENPROD' then
  Form1.GO_PROC(Form1.QMINCENPROD,s1) else
if s1='KREDIT' then
  Form1.GO_PROC(Form1.QKREDIT,s1);
  out_str:=s1;
end;




initialization
 TTypedComObjectFactory.Create(ComServer, Tnaklper, Class_naklper,
   ciMultiInstance, tmFree);

end.


Это сообщение отредактировал(а) Alex - 25.2.2005, 22:10
PM MAIL   Вверх
Александра
Дата 25.2.2005, 15:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 219
Регистрация: 20.2.2005
Где: Москва

Репутация: 7
Всего: 12



maxim1000
совершенно верно!

а насчет компонет, почитай у Андрюшки Чудина из Библио Глобуса: http://cpr.biblio-globus.ru/mailslots.htm
--------------------
PM   Вверх
z-END
Дата 25.2.2005, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прафесар™
****


Профиль
Группа: Комодератор
Сообщений: 3014
Регистрация: 13.3.2003
Где: Венья, Пиетари

Репутация: 11
Всего: 102



Цитата(bursa @ 25.2.2005, 15:48)
RPC-удаленный вызов процедур

мой файрволл, данное творение недопускает, т.к. очень опасное это дело.


--------------------
Каждый чилавек пасвоему праф...а памоему НЕТ! 

PM WWW ICQ   Вверх
Bes
Дата 25.2.2005, 16:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 806
Регистрация: 8.12.2004

Репутация: 5
Всего: 7



2ALL!!!
Спасибо ребята, на выходных буду разбираться со всей этой кучей информации которой вы меня завалили. Спасибо.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0635 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.