Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Delphi (до версии 2009) - часть 5

Модерирует : ShIvADeSt

ShIvADeSt (19-05-2010 05:14): Продолжаем тут http://forum.ru-board.com/topic.cgi?forum=33&topic=11215  Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

   

ShIvADeSt



Moderator
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Продолжение темы Вопросы по Delphi (до версии 2009) - часть 4

Познаем сами, помогаем другим...
Обсуждаем вопросы, не связанные с юникоидными версиями Delphi - для этого есть соответствующая тема (см. ссылки ниже).

Правила топика:
    Прежде чем спрашивать:
  1. Желательно изучить вопрос, попытаться найти ответ в прилагаемых мануалах, хелпах и анализируя исходники.
  2. Выполнить поиск по топику (открыть "Версия для печати" и поискать ответ там).
  3. Применить фильтр по разделу "Прикладное программирование". Ответы на многие старые вопросы могли быть даны в отдельных темах.
  4. Продумайте вопрос. На поверхностные вопросы вы получите поверхностные ответы, или вообще ответов не получите.
  5. Желательно указывать версии используемого компилятора и операционной системы.
    Прежде чем отвечать:
  1. Если не можете помочь, не мешайте.
  2. Если уж вы отвечаете на вопрос, давайте ответ по сути.
  3. Если вы не уверены, так и говорите! Ошибочный, но авторитетно звучащий ответ хуже, чем отсутствие ответа.
  4. Задавайте дополнительные вопросы, чтобы получить больше информации.
  • Отсутствие ответа не равносильно игнорированию - иногда участники форума просто не знают ответ. Повторная посылка вопроса не приветствуется. Посты типа "неужели никто не знает ответа..." или "может мне все-таки кто-нибудь ответит" недопустимы.  
  • Все большие куски кода (более 5 строк) оформляем в тег [morе] дабы уменьшить размер поста. FAQ по тегу [morе].

  • Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 02:09 28-06-2009 | Исправлено: psa1974, 12:00 02-02-2010
    psa1974



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    maix

    Цитата:
     2010

    Так и есть - 800 Кб - нормальный размер для этой версии Дельфи. В 7 Дельфи пустой проект весит порядка 300 Кб. Все дело в том что даже если приложение состоит из одной формы и ничего не делает, все равно подключается VCL.
     
    KOL - альтернатива VCL, бесплатная библиотека, позволяющая разрабатывать на Delphi компактные программы. Взять можно здесь: http://kolmck.net Но все равно получаемый экзешник в 2010 Дельфи будет больше чем в предыдущих версиях Дельфи из-за нововведений в RTTI.

    Всего записей: 438 | Зарегистр. 08-11-2005 | Отправлено: 14:29 20-11-2009
    data man



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    maix
    Есть Вопросы по Delphi 2010 (Weaver)
    Там в шапке (да и топик полезно почитать) написано, как уменьшить размер exe-файла, отключив новые RTTI-возможности D2010.

    ----------
    Любой достаточно развитый тролль неотличим от подлинно помешанного на какой-либо идее.
    Кекс. Антибиотики. Ламбада.

    Всего записей: 1696 | Зарегистр. 13-10-2005 | Отправлено: 14:32 20-11-2009
    psa1974



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Чтобы почувствовать что такое VCL, сделай консольную программу - получишь экзешник размером 100 кб.  
    А вообще Дельфи 2010 не преследует цель написания программ минимального размера. Она для тех что любит роскошь и комфорт. А хочешь писать минимальные проги - бери Дельфи 3, будешь сильно удевлен малым размером. Вон, например, Total commander дор сих пор на Дельфи 3 пишется...

    Всего записей: 438 | Зарегистр. 08-11-2005 | Отправлено: 14:34 20-11-2009 | Исправлено: psa1974, 15:19 20-11-2009
    mdid

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    создаю в PopupMenu программно submenu которое формируется по onPopUp

    Код:
     
        mi:=TMenuItem.Create(self);
        mi.Caption:=ds.DataSet.FieldByName('Наименование').AsString;
        mi.Tag:=ds.DataSet.FieldByName('ID').AsInteger;
        mi.OnClick:=ReplaceItem;
        TMenuItem(Sender).Insert(i,mi);
     

     
     
    и столкнулся с тем что срабатывает onClick при открытии submenu...как это вылечить?

    Всего записей: 1298 | Зарегистр. 13-02-2006 | Отправлено: 15:54 20-11-2009 | Исправлено: mdid, 16:08 20-11-2009
    ShIvADeSt



    Moderator
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    psa1974

    Цитата:
    Чтобы почувствовать что такое VCL, сделай консольную программу - получишь экзешник размером 100 кб.  

    Странно, у меня при создании консольного приложения размер не превышает 20 килов. Пишу для версии Дельфи 5, но не думаю в 2010 умудрились в базовые модули засунуть столько мусора.

    ----------
    И создал Бог женщину... Существо получилось злобное, но забавное...

    Всего записей: 3956 | Зарегистр. 29-07-2003 | Отправлено: 16:13 20-11-2009 | Исправлено: ShIvADeSt, 16:14 20-11-2009
    psa1974



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    mdid
    onClick надо назначать не самому субменю, а пунктам этого субменю, а их в своем примере вообще не создаешь. В итоге твое субменю ведет себя как обычный пункт меню.
     
    Добавлено:
    ShIvADeSt

    Цитата:
    у меня при создании консольного приложения размер не превышает 20 килов

    Совершенно согласен! Я когда на Дельфи 7 писал консольное приложение, состоящее из 2 строк: поиска окна диспетчера задач и прибивания его (ну, надо было ), то его размер был ровно 15360 байт. И когда сейчас я писал свой пост, я такую цифру сперва и написал, но потом все-таки решил запустить Дельфи 2010 и проверить... Итог (добайтно): 113664 байт, а поскольку maix вооружился именно Дельфи 2010, то я такую цифру и привел.
     
    Ою этом я и говорю: Дельфи 2010 - не для компактного размера программ. За удобства надо "платить" размером...

    Всего записей: 438 | Зарегистр. 08-11-2005 | Отправлено: 16:19 20-11-2009 | Исправлено: psa1974, 16:30 20-11-2009
    Odysseos



    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    maix
     

    Цитата:
    А вот можете подсказать какой-нибудь нормальный компилер для delphi чтобы размер приложений был меньше чем со встроенным. Желательно со ссылками и как их туда установить

     
    В нынешние времена гигабайт оперативной памяти и мегабитных сетевых каналов уместен такой вопрос - а зачем, собственно, уменьшать размер приложения с целью сэкономить килобайты?.. Особенно учитывая, что весь современный софт (выполняющий хоть сколько-нибудь серьёзную работу) ворочает данными, превосходящими размер кода во многие тысячи раз.

    Всего записей: 186 | Зарегистр. 02-01-2006 | Отправлено: 00:23 21-11-2009
    SIgor33

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Есть код
    var
    s: TSocket;
    WSData: WSAData;
    Protocol: Integer;
    sAddr: sockaddr_in;
    buf: array[0..255] of Char;
    iRecv: Integer;
    begin
    if (WSAStartup($0101,WSData)<>0) then Halt(1);
    Protocol:=IPPROTO_TCP;
    s:=socket(AF_INET,SOCK_STREAM,Protocol);
    if (s=INVALID_SOCKET) then Halt(2);
    ZeroMemory(@sAddr,sizeof(sAddr));
    sAddr.sin_family:=PF_INET;
    sAddr.sin_port:=htons(PORT);
    sAddr.sin_addr.S_addr:=inet_addr(IP_ADDRESS);
    if (connect(s,sAddr,sizeof(sockaddr_in))=SOCKET_ERROR) then
    begin
    writeln('Error');
    closesocket(s);
    WSACleanup;
    exit;
    end;
    writeln('Connected');
    closesocket(s);
    WSACleanup;
    end.
     
     
    подключаемся к удаленному сокету , если он есть все быстро и нормально
    если компьютер отсутствует , долго висит ...
    необходимо при отсутствии компьютера в сети сразу выводить ERROR

    Всего записей: 652 | Зарегистр. 03-03-2009 | Отправлено: 11:47 21-11-2009
    ppkp

    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Попробуйте
     
    try
       connect(s,sAddr,sizeof(sockaddr_in));
    except
     On EConnectError do begin// тут я не помню точно название
        writeln('Error');  
        closesocket(s);  
        WSACleanup;
      end;
    end;

    Всего записей: 480 | Зарегистр. 13-04-2006 | Отправлено: 15:38 21-11-2009 | Исправлено: ppkp, 12:06 23-11-2009
    NOwlar



    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    ppkp
    connect не поднимает исключений.
     
    SIgor33
    К сожалению, очевидного решения для установки таймаута  при недоступности удалённого узла нет. Вот тут статейка описывающая нюансы при вызове connect, предлагающая следующее решение: использовать неблокирующие сокеты. В таком случае вызов connect() сразу же вернётся с SOCKET_ERROR, а вызов WSAGetLastError вернёт 'WSAEWOULDBLOCK', а сам процесс подключения будет происходить дальше. Мы можем подождать нужное нам количество времени (timeout) и проверить состояние сокета, вызвав функцию, которая требует подключенного сокета, например 'getpeername()' or 'recv()'.  Если вернётся ошибка, а  WSAGetLastError вернёт 'WSAENOTCONN', то мы можем смело предположить, что сокет не подключен и закрыть его. Единственный минус этого подхода состоит в том, что даже если подключение происходит быстро, мы узнаем об этом только через timeout времени. Отрицаттельный эффект можно уменьшить, проверяя состояние сокета через малые интервалы времени, и прекратить проверки, когда в сумме пройдёт timeout времени.
     
    Ещё можно использовать какой-нибудь готовый компонент, например TIdTCPClient из набора Indy 10, где есть свойство ConnectTimeout.

    Всего записей: 170 | Зарегистр. 25-01-2006 | Отправлено: 13:39 23-11-2009
    mdid

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    psa1974

    Цитата:
    mdid  
    onClick надо назначать не самому субменю, а пунктам этого субменю, а их в своем примере вообще не создаешь. В итоге твое субменю ведет себя как обычный пункт меню.

    эмм...а можно по подробней как?
    вот полный код то как я делал

    Код:
     
    var
      ds  : TDataSource;
      q   : TADOQuery;
      MI  : TMenuItem;
      i   : Integer;
    begin
      if folder='-1' then
        TPopupMenu(Sender).Items[4].Clear;
      ds:=TDataSource.Create(nil);
      q:=TADOQuery.Create(nil);
      ds.DataSet:=q;
      q.Connection:=Form2.ADOConnection1;
      q.SQL.Text:='select * from '+GetTableFromId(true,TableID)+' where (Тип=''0'') and (Принадлежит='''+Folder+''')';
      q.Open;
      ds.DataSet.First;
      for I:=0 to ds.DataSet.RecordCount - 1 do begin
        mi:=TMenuItem.Create(self);
        mi.Caption:=ds.DataSet.FieldByName('Наименование').AsString;
        mi.Tag:=ds.DataSet.FieldByName('ID').AsInteger;
        selItem.id_DestGr:=ds.DataSet.FieldByName('ID').AsInteger;
        mi.OnClick:=ReplaceItem;
        if folder='-1' then
          TPopupMenu(Sender).Items[4].Insert(i,mi)
        else
          TMenuItem(Sender).Insert(i,mi);
        CreateListFolder(mi,inttostr(mi.Tag));
        ds.DataSet.Next;
      end;
      ds.Destroy;
      q.Destroy;
     

    тоесть выбирает из справочника группы и строит дерево

    Всего записей: 1298 | Зарегистр. 13-02-2006 | Отправлено: 13:53 23-11-2009
    scroollocker

    Newbie
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    Здравствуйте, подскжите пожалуйста, как можно Замутить перемещение окошка программы без панельки (на которой, еще есть кнопочки:закрыть, минимизировать.., за которую обычно и перемещают окошко)
    Знаю функцию SetWindowPos, но как узнать, на сколько пользователь переташил окно?

    Всего записей: 5 | Зарегистр. 10-10-2007 | Отправлено: 15:34 23-11-2009 | Исправлено: scroollocker, 16:03 23-11-2009
    JDEE

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    scroollocker
     

    Цитата:
    Здравствуйте, подскжите пожалуйста, как можно Замутить перемещение окошка программы без панельки

     

    Код:
     
      TForm1 = class(TForm)
      private
        {Для перемещения формы вне заголовка объявляем процедуру}
        procedure WMNCHitTest(var M:TWMNCHitTest);message wm_NCHitTest;
      public
        { Public declarations }
    end;
     
    procedure TForm1.WMNCHitTest(var M: TWMNCHitTest);
    begin
      inherited;
      if M.Result = htClient then
        M.Result := htCaption;
    end;
     
     

    Всего записей: 59 | Зарегистр. 30-11-2004 | Отправлено: 16:21 23-11-2009
    scroollocker

    Newbie
    Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
    JDEE
    Спасибо огромное! Эх жалко не будут работать события мышки.. А без этого никак нельзя?

    Всего записей: 5 | Зарегистр. 10-10-2007 | Отправлено: 17:16 23-11-2009 | Исправлено: scroollocker, 17:41 23-11-2009
    SIgor33

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    NOwlar
    спасибо за ссылку я тоже склонился к просмотру Timeout.

    Всего записей: 652 | Зарегистр. 03-03-2009 | Отправлено: 17:25 23-11-2009
    JDEE

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    scroollocker

    Цитата:
    Эх жалко не будут работать события мышки.. А без этого никак нельзя?

     
    Как то так:

    Код:
     
     TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
        procedure FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
        procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
      private
        IsDown: Boolean;
        MX, MY: Integer;
      public
        { Public declarations }
      end;
     
    procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    begin
      IsDown := True;
      MX := X;
      MY := Y;
    end;
     
    procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    begin
      if IsDown then
      begin
        Left := Left + (X - MX);
        Top := Top + (Y - MY);
      end;
    end;
     
    procedure TForm1.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    begin
      IsDown := False;
    end;
     

    Всего записей: 59 | Зарегистр. 30-11-2004 | Отправлено: 18:18 23-11-2009
    AndreusB



    Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Если устанавливать Delphi 2010 и Visual Sudio 2008 SP1(.NET 3.5 SP1), то в какой последовательности. Есть зависимости?

    Всего записей: 212 | Зарегистр. 20-07-2008 | Отправлено: 18:45 23-11-2009
    JDEE

    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    AndreusB
    Ставил сначала дельфу потом студию. Никаких проблем не замечено.  
     
    PS: Студию уже 2010 ИМХО имеет смысл ставить. Там много всего вкусного.

    Всего записей: 59 | Зарегистр. 30-11-2004 | Отправлено: 18:50 23-11-2009
    NOwlar



    Junior Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    JDEE
    По-моему, это не будет работать.
     
    scroollocker
    попробуй так  

    Код:
     
    procedure TForm1.WMNCHitTest(var M: TWMNCHitTest);  
    begin  
      inherited;  
      if M.Result = htClient then begin
        if (nil = ControlAtPos( ScreenToClient( Point( M.XPos, M.YPos )), False, True ))
        then M.Result := htCaption;  
      end;
    end;  
     

    тогда на всех контролах будет как обычно, а за остальную часть форму можно будет таскать.

    Всего записей: 170 | Зарегистр. 25-01-2006 | Отправлено: 18:59 23-11-2009
    psa1974



    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    mdid
    Вот все от того что не полную инфу сразу привел . Возможны 2 варианта:
     
    1. Твой код по созданию подменю правильный. Пункты меню, в том числе TPopupMenu(Sender).Items[4] создан в режиме разработки. Скорее всего, у тебя в инспекторе объектов для пункта  TPopupMenu(Sender).Items[4] прописан обработчик события, который и вызывается.
     
    2. Твой код по созданию подменю не правильный. Собственно пункты меню ты создаешь динамически (в том числе и TPopupMenu(Sender).Items[4]). Возможен случай, когда при folder <>'-1' строкой TMenuItem(Sender).Insert(i,mi); ты собственно и создаешь свой пункт меню TPopupMenu(Sender).Items[4] (и автоматом назначаешь ему обработчик, поскольку тут в цикле он добавляется во все вновь созданные пункты вне зависимости ни от чего). А впоследствии назначаешь этому пункту меню элементы субменю.  
    Убедиться можно так:

    Цитата:
     
        if folder='-1' then  
        begin
          if Assigned(TPopupMenu(Sender).Items[4].OnClick) then
            ShowMessage('Таки обработчик назначен ');
          TPopupMenu(Sender).Items[4].Insert(i,mi);
        end;
        else  
          TMenuItem(Sender).Insert(i,mi);
     

     
    Я бы написал так:

    Цитата:
     
      for I:=0 to ds.DataSet.RecordCount - 1 do
      begin
        mi:=TMenuItem.Create(self);
        mi.Caption:=ds.DataSet.FieldByName('Наименование').AsString;
        mi.Tag:=ds.DataSet.FieldByName('ID').AsInteger;
        selItem.id_DestGr:=ds.DataSet.FieldByName('ID').AsInteger;
        if (folder='-1') or ((folder<>'-1') and (i <> 4)) then { гарантированно назначаем обработчик только подпунктам субменю, формируемым для пункта TPopupMenu(Sender).Items[4], либо другим основным пунктам меню, для которых ты не создаешь субменю. Может условие не совсем точно, но идею ты понял }
          mi.OnClick:=ReplaceItem;
        if folder='-1' then
          TPopupMenu(Sender).Items[4].Insert(i,mi)
        else
          TMenuItem(Sender).Insert(i,mi);  
        CreateListFolder(mi,inttostr(mi.Tag));
        ds.DataSet.Next;
      end;
     

    Это не существенно, но чего бы не написать вместо TMenuItem(Sender).Insert(i,mi) TMenuItem(Sender).Add(mi)? Все равно ж i с нуля отсчитывается...

    Всего записей: 438 | Зарегистр. 08-11-2005 | Отправлено: 19:08 23-11-2009 | Исправлено: psa1974, 19:32 23-11-2009
       

    Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

    Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы по Delphi (до версии 2009) - часть 5
    ShIvADeSt (19-05-2010 05:14): Продолжаем тут http://forum.ru-board.com/topic.cgi?forum=33&topic=11215


    Реклама на форуме Ru.Board.

    Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
    Modified by Ru.B0ard
    © Ru.B0ard 2000-2024

    BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

    Рейтинг.ru