Рассылка закрыта
При закрытии подписчики были переданы в рассылку "Бизнес и карьера в интернете" на которую и рекомендуем вам подписаться.
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
нет.
Информационный Канал Subscribe.Ru |
Познавательное программирование
(comp.soft.prog.urisprog)Выпуск 22
Здравствуйте, Уважаемые подписчики!4>
Самый большой скачок в производительности и самые большие перемены в стиле работы готовит нам переход на широкомасштабное использование сетей.
- Билл Гейтс.
На заметку
Помещаю решения моей задачи из института, о которой речь шла ранее:
/*
Задано натуральное число n. Найти и напечатать все такие числа,
не превосходящие n, которые делятся на каждую из своих цифр.
В программе определить функцию, позволяющую выяснить, делится ли заданное
натуральное число на каждую из своих цифр.
*/
- Хотя господин Alf и "не разделил восторг автора по поводу редкой оригинальности задачи" :), тем не менее он убрал из моей версии лишние детали:
#include <stdio.h>
int Check(long i)
{
  int C = 0;
  short d;
  long n = i;
  while (!C && (n > 0))
  {
    d = n % 10;
    if (d)
    {
      C = i % d;
      n /= 10;
    }
    else
      C = 1;
  }
  return !C;
}
int main(int argc, char* argv[])
{
  long n = 100;
  for (long i=1; i<=n; i++)
    if (Check(i))
      printf("%d\n", i);
    return 0;
}
- А вот Дмитрию Максимову задача понравилась, он решал её 10 минут:
#include "stdafx.h"
bool IsNeed(int n)
{
        int k = n;
        while( k )
        {
                // Получаем последнюю цифру
                int digit = k % 10;
                if ( digit && ( n % digit ) )
                {
                        return false;
                }
                k /= 10;
        }
        return true;
}
int main()
{
        const int n = 1000;
        for(int i = 0; i <= n; ++i)
        {
                if ( IsNeed(i) )
                {
                        printf("%d ",i);
                }
        }
        return 0;
}
- Вариант от Дмитрия Плотникова:
#include <iostream>
#include <CONIO.H>
 
#define N 100000
 
inline bool TestDigit(int Digit){
 int CurDigit,End=Digit;
 while ( End!=0 ) {
  CurDigit=End%10;
  End/=10;
  if ( CurDigit!=0 && (Digit%CurDigit) )
   return false;
 }
 return true;
}
 
int main()
{
  for ( int i=1;i<=N;i++ ) {
  if ( TestDigit(i) ) std::cout<<i<<' '<<std::flush;
  }
 getch();
 return 0;
}
- Вариант не представившегося владельца e-mail twilight_sun@...:
#include "stdio.h"
int test(int n)
{ int r,res;
  for(r=n,res=1;r&&(res=!(n%(r%10)));r/=10);
  return res;
}
void main()
{
  int i=1,n;
  printf("nn :-> ");scanf("%i",&n);
  for(;i<=n;++i)if (test(i)) printf("%i ",i);
}
- А вот "приз" за САМОЕ ИЗВРАЩЁННОЕ РЕШЕНИЕ :) (при этом, судя по всему, достаточно быстрое, тем не менее) достаётся программисту по имени Raptor, встречайте:
BOOL CTestDivDlg::TestNumber1(DWORD dwNumber)
{
     DWORD dwTemp;
     BOOL IsDiv[8]; // 2 3 4 5 6 7 8 9
     memset(IsDiv,0,sizeof(BOOL)*8);
     // 2
     if((dwNumber&0x01)==0)
     IsDiv[0]=TRUE;
     // 3
     dwTemp=dwNumber*0xaaaaaaab;
     if(dwTemp<=0x55555555)
     IsDiv[1]=TRUE;
     // 4
     dwTemp=dwNumber>>1;
     if(((dwTemp&0x01)==0)&&IsDiv[0])
     IsDiv[2]=TRUE;
     // 5
     dwTemp=dwNumber*0xcccccccd;
     if(dwTemp<=0x33333333)
     IsDiv[3]=TRUE;
     // 6
     dwTemp=dwNumber;
     if(IsDiv[0]&&IsDiv[1])
     IsDiv[4]=TRUE;
     // 7
     dwTemp=dwNumber*0xb6db6db7;
     if(dwTemp<=0x24924924)
     IsDiv[5]=TRUE;
     // 8
     dwTemp=dwNumber>>2;
     if(((dwTemp&0x01)==0)&&IsDiv[2])
     IsDiv[6]=TRUE;
     // 9
     dwTemp=dwNumber*0x38e38e39;
     if(dwTemp<=0x1c71c71c)
     IsDiv[7]=TRUE;
/*
  // проверяем число
     while (dwNumber>0)
  {
  if(IsDiv[(dwNumber%10)+2]==FALSE)
  return FALSE;
  dwNumber/=10;
  }
  return TRUE;
*/
  dwTemp=0;
     while(dwNumber>999999999)
     {
          dwTemp+=1;
          dwNumber-=1000000000;
     }
     if((dwTemp>1)&&(IsDiv[dwTemp-2]==FALSE))
    return FALSE;
     dwTemp=0;
     while(dwNumber>99999999)
     {
          dwTemp+=1;
          dwNumber-=100000000;
     }
     if((dwTemp>1)&&(IsDiv[dwTemp-2]==FALSE))
    return FALSE;
     dwTemp=0;
     while(dwNumber>9999999)
     {
          dwTemp+=1;
          dwNumber-=10000000;
     }
     if((dwTemp>1)&&(IsDiv[dwTemp-2]==FALSE))
    return FALSE;
    dwTemp=0;
     while(dwNumber>999999)
     {
          dwTemp+=1;
          dwNumber-=1000000;
     }
     if((dwTemp>1)&&(IsDiv[dwTemp-2]==FALSE))
     return FALSE;
    dwTemp=0;
    while(dwNumber>99999)
    {
          dwTemp+=1;
          dwNumber-=100000;
    }
    if((dwTemp>1)&&(IsDiv[dwTemp-2]==FALSE))
    return FALSE;
    dwTemp=0;
    while(dwNumber>9999)
    {
         dwTemp+=1;
        dwNumber-=10000;
    }
    if((dwTemp>1)&&(IsDiv[dwTemp-2]==FALSE))
    return FALSE;
    dwTemp=0;
    while(dwNumber>999)
    {
         dwTemp+=1;
         dwNumber-=1000;
    }
    if((dwTemp>1)&&(IsDiv[dwTemp-2]==FALSE))
    return FALSE;
    dwTemp=0;
    while(dwNumber>99)
    {
         dwTemp+=1;
         dwNumber-=100;
    }
    if((dwTemp>1)&&(IsDiv[dwTemp-2]==FALSE))
    return FALSE;
    dwTemp=0;
    while(dwNumber>9)
    {
         dwTemp+=1;
         dwNumber-=10;
    }
    if((dwTemp>1)&&(IsDiv[dwTemp-2]==FALSE))
    return FALSE;
    if((dwNumber>1)&&(IsDiv[dwNumber-2]==FALSE))
    return FALSE;
    return TRUE;
}
Вопрос - ответ
Вопрос Максима:
Здравствуйте. Подскажите пожалуйста как сделать в Delphi так, чтобы при
работе программы в трее отображался её значок?
Ваши ответы присылайте на urisff@inbox.ru
Ваши вопросы по программированию вы можете прислать по адресу urisff@inbox.ru и остальные подписчики помогут вам найти решение.
Далее следует сборник вопросов-ответов от соавтора рассылки №1 Сергея Гусева.
Вопрос-Ответ:
Выпуск #1
1. В нескольких программах видел, что при нажатии на пункт меню он становился выделенным
галочкой, а при повторном нажатии это выделение пропадало. Как мне это сделать в своей
программе ?
procedure TForm1.mnuFileClick(Sender: TObject);
begin
If mnuFile.Checked = False Then
Begin
mnuFile.Checked:=True;
ShowMessage('Пункт меню отмечен !!!');
End
Else
If mnuFile.Checked = True Then
Begin
mnuFile.Checked:=False;
ShowMessage('Пункт меню не отмечен !!!');
End;
end;
2. Как вывести текст поверх картинки загруженной в Image ?
procedure TForm1.FormCreate(Sender: TObject);
Var BMP : TBitmap;
begin
BMP:=TBitmap.Create;
BMP.LoadFromFile('MyPicture.bmp');
Image1.Picture.Assign(BMP);
Image1.Canvas.Brush.Color:=clBlue;
Image1.Canvas.Font.Name:='Arial';
Image1.Canvas.Font.Size:=10;
Image1.Canvas.TextOut(10, 10, 'Некоторый текст !!!');
end;
3. При выполнении большого цикла мое приложение как бы замирает. Можно ли это как-то исправить ?
Для этого нужно в тело цикла вставить конструкцию Application.ProcessMessages. При этом можно
будет нажимать на различные кнопки, пользоваться меню, но нельзя будет закрыть приложение :(.
procedure TForm1.Button1Click(Sender: TObject);
Var I: Integer;
begin
For I:=1 To 100000 Do
Begin
Label1.Caption:=IntToStr(I);
Application.ProcessMessages;
End;
end;
4. При удалении записи в БД выдается запрос на английском языке, хотя вся моя программа построена
на русском языке. Можно ли как-нибудь сделать этот запрос русским ?
Я тоже столкнулся с такой неприятной мелочью. Лично мне пришла в голову одна очень простая мысль:
я сделал отдельный пункт меню "Удалить запись", в котором я написал свой обработчик удаления
записи из набора данных с русским диалоговым запросом. Далее я задал свойству пункта меню
ShortCut (быстрый доступ "горячей клавишей") значение
Ctrl+Del. Еще можно просто запретить вывод запроса на удаление
путем установки значения False подсвойству dgComfirmDelete свойства сетки
DBGrig, но это не очень хорошо, потому что можно и не заметить как запись будет
удалена. Вот небольшой и понятный пример:
procedure TForm1.mnuDBDelClick(Sender: TObject);
begin
If Application.MessageBox('Удалить запись ?', 'Удаление:', MB_YESNO) = idYES
Then Table1.Delete;
end;
5. Как написать свой ScreenSaver ?
Честно говоря, я даже никогда об этом не задумывался :). По сути ScreenSaver - это
обычная программа переименованная в расширение .scr. Даже если Вы любую программу
переименуете из .exe в .scr, и поместите в каталог Windows или
Windows\System, то через установленный промежуток времени
переименованная программа сработает как ScreenSaver. Значит нужно написать свою собственную
программу и в обработчики нажатия клавиш onKeyPress, onKeyDown и onKeyUp записать код закрытия
программы. Аналогичным образом нужно "оформить" обработчики движения мыши. А еще надо проверять,
чтобы программа запускалась в одном экземпляре, иначе таких хранителей экрана будет одновременно
запущено сразу несколько :).
6. Во многих программах выдаются диалоги для ввода некоторых значений, например, пароля.
А как это делается, неужели создается отдельная форма ?
Для этого, безусловно, можно создать отдельную форму, но проще будет воспользоваться функциями
InputBox или InputQuery. В своих
программах с БД я частенько использую такой прием для перехода к определенной записи. Вот небольшой
и понятный пример:
procedure TForm1.mnuDBGotoClick(Sender: TObject);
Var Go: String;
begin
Go:='1';
InputQuery('Переход к записи', 'Перейти к записи с номером:', Go);
Try
If NOT Table1.Locate('Code', Go, []) Then
MessageDlg('Запись с номером' + Go + 'не найдена', mtWarning, [mbOK], 0);
Except
MessageDlg('Значение' + Go + 'не допустимо', mtWarning, [mbOK], 0);
End;
end;
7. При вводе текста в Memo и достижении правого края контрола текст автоматически переносится
на новую строку. Как с этим бороться ?
Для этого можно поступить двумя способами:
1) Установить свойству WordWrap значение False.
2) Установить свойству ScrollBars значение ssHorizontal - для появления горизонтальной полосы
прокрутки, или ssBoth - для появления обоих полос прокрутки.
8. Как можно программно управлять открытием и закрытием компонента ComboBox и узнать его
состояние в текущий момент ?
procedure TForm1.Button1Click(Sender: TObject);
begin
//Открываем список
ComboBox1.DroppedDown:=True;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
//Закрываем список
ComboBox1.DroppedDown:=False;
end;
procedure TForm1.Bla-Bla-Bla(Sender: TObject);
begin
If ComboBox1.DroppedDown = True Then ShowMessage('Список открыт')
Else ShowMessage('Список закрыт')
end;
9. В программе 1С я заметил, что при редактировании ячейки БД в правой ее части появляется
кнопка с тремя точками. Если нажать эту кнопку, то появляется отдельная форма для выбора товара.
А можно ли такое сделать в Делфи ?
Конечно можно, для этого нужно воспользоваться т.н. статическими полями (о них я рассказывал в
одной из статей о БД). Для определенного статического поля нужно установить свойство
ButtonStyle в значение cbsEllipsis.
А затем обрабатывать событие onEditButtonClick сетки DBDrid.
procedure TForm1.DBGrid1EditButtonClick(Sender: TObject);
begin
FormAdd2.ShowModal;
end;
10. Как программно создать компонент и навесить на него обработчик события?
uses ..., StdCtrls;
...
procedure TForm1.FormCreate(Sender: TObject);
Var Memo1 : TMemo;
begin
Memo1:=TMemo.Create(Self);
Memo1.Parent:=Form1;
Memo1.Top:=10;
Memo1.Left:=10;
Memo1.Height:=90;
Memo1.Width:=150;
Memo1.OnKeyPress:=MyMemoKeyPress;
end;
procedure TForm1.MyMemoKeyPress(Sender: TObject; var Key: Char);
begin
If NOT(Key In ['0'..'9', Chr(8), Chr(32)]) Then Key:=Chr(0);
end;
11. Можно ли в процессе выполнения программы узнать какой разделитель целой и дробной
части установлен в системе в данный момент, а то эти ошибки уже задолбали ?
Разделитель в своей программе можно задать свой. А так для этого служит DecimalSeparator.
procedure TForm1Main.FormCreate(Sender: TObject);
begin
DecimalSeparator:='.';
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage('Текущий разделитель: ' + DecimalSeparator);
Edit1.Text:='10' + DecimalSeparator + '5';
end;
12. Как установить курсор мыши в определенную позицию экрана ?
procedure TForm1.Button1Click(Sender: TObject);
Var P: TPoint;
begin
GetCursorPos(P); // Сохраняем позицию курсора
...
// Что-то делаем
...
SetCursorPos(P.X, P.Y); // Восстанавливаем позицию курсора
end;
13. Хочу при запуске программы сделать кнопку активной, но постоянно выдается ошибка.
Как лечить ?
Если уже Вы решили сделать кнопку активной в обработчике события создания формы, то нужно просто
вставить обработчик исключительной ситуации, которая как раз и генерируется. Но при компиляции
проекта это исключение все равно будет возникать, что очень не удобно. Более простым и удобным
способом будет использовать событие формы onShow. Тогда уж точно никаких ошибок не возникнет.
procedure TForm1.FormCreate(Sender: TObject);
begin
Try
If Button1.CanFocus Then Button1.SetFocus;
Except
End;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
If Button1.CanFocus Then Button1.SetFocus;
end;
14. Как из моей программы некоторый файл сделать скрытым ?
Для этого ему нужно задать атрибут как "скрытый".
procedure TForm1.FormCreate(Sender: TObject);
begin
SetFileAttributes('File.txt', FILE_ATTRIBUTE_HIDDEN);
end;
15. Где можно взять архивы и учебники по Delphi?
Самый оптимальный вариант изучения любого языка программирования - это хорошая книга, электронные
источники и исходники. Я конечно не уверен, может быть некоторые ссылки уже умерли,
но все же...
P.S.: Для уменьшения объема рассылки все вопросы были отредактированы !!!
Любые комментарии, жалобы, пожелания и сообщения об ошибках настоятельная просьба
присылать на e-mail.
Статьи
- Билл Гейтс.
На заметку
int Check(long i)
{
  int C = 0;
  short d;
  long n = i;
  while (!C && (n > 0))
  {
    d = n % 10;
    if (d)
    {
      C = i % d;
      n /= 10;
    }
    else
      C = 1;
  }
  return !C;
}
int main(int argc, char* argv[])
{
  long n = 100;
  for (long i=1; i<=n; i++)
    if (Check(i))
      printf("%d\n", i);
    return 0;
}
bool IsNeed(int n)
{
        int k = n;
        while( k )
        {
                // Получаем последнюю цифру
                int digit = k % 10;
                if ( digit && ( n % digit ) )
                {
                        return false;
                }
                k /= 10;
        }
        return true;
}
int main()
{
        const int n = 1000;
        for(int i = 0; i <= n; ++i)
        {
                if ( IsNeed(i) )
                {
                        printf("%d ",i);
                }
        }
        return 0;
}
#include <CONIO.H>
 
#define N 100000
 
inline bool TestDigit(int Digit){
 int CurDigit,End=Digit;
 while ( End!=0 ) {
  CurDigit=End%10;
  End/=10;
  if ( CurDigit!=0 && (Digit%CurDigit) )
   return false;
 }
 return true;
}
 
int main()
{
  for ( int i=1;i<=N;i++ ) {
  if ( TestDigit(i) ) std::cout<<i<<' '<<std::flush;
  }
 getch();
 return 0;
}
int test(int n)
{ int r,res;
  for(r=n,res=1;r&&(res=!(n%(r%10)));r/=10);
  return res;
}
void main()
{
  int i=1,n;
  printf("nn :-> ");scanf("%i",&n);
  for(;i<=n;++i)if (test(i)) printf("%i ",i);
}
{
     DWORD dwTemp;
     BOOL IsDiv[8]; // 2 3 4 5 6 7 8 9
     memset(IsDiv,0,sizeof(BOOL)*8);
     // 2
     if((dwNumber&0x01)==0)
     IsDiv[0]=TRUE;
     // 3
     dwTemp=dwNumber*0xaaaaaaab;
     if(dwTemp<=0x55555555)
     IsDiv[1]=TRUE;
     // 4
     dwTemp=dwNumber>>1;
     if(((dwTemp&0x01)==0)&&IsDiv[0])
     IsDiv[2]=TRUE;
     // 5
     dwTemp=dwNumber*0xcccccccd;
     if(dwTemp<=0x33333333)
     IsDiv[3]=TRUE;
     // 6
     dwTemp=dwNumber;
     if(IsDiv[0]&&IsDiv[1])
     IsDiv[4]=TRUE;
     // 7
     dwTemp=dwNumber*0xb6db6db7;
     if(dwTemp<=0x24924924)
     IsDiv[5]=TRUE;
     // 8
     dwTemp=dwNumber>>2;
     if(((dwTemp&0x01)==0)&&IsDiv[2])
     IsDiv[6]=TRUE;
     // 9
     dwTemp=dwNumber*0x38e38e39;
     if(dwTemp<=0x1c71c71c)
     IsDiv[7]=TRUE;
/*
  // проверяем число
     while (dwNumber>0)
  {
  if(IsDiv[(dwNumber%10)+2]==FALSE)
  return FALSE;
  dwNumber/=10;
  }
  return TRUE;
*/
  dwTemp=0;
     while(dwNumber>999999999)
     {
          dwTemp+=1;
          dwNumber-=1000000000;
     }
     if((dwTemp>1)&&(IsDiv[dwTemp-2]==FALSE))
    return FALSE;
     dwTemp=0;
     while(dwNumber>99999999)
     {
          dwTemp+=1;
          dwNumber-=100000000;
     }
     if((dwTemp>1)&&(IsDiv[dwTemp-2]==FALSE))
    return FALSE;
     dwTemp=0;
     while(dwNumber>9999999)
     {
          dwTemp+=1;
          dwNumber-=10000000;
     }
     if((dwTemp>1)&&(IsDiv[dwTemp-2]==FALSE))
    return FALSE;
    dwTemp=0;
     while(dwNumber>999999)
     {
          dwTemp+=1;
          dwNumber-=1000000;
     }
     if((dwTemp>1)&&(IsDiv[dwTemp-2]==FALSE))
     return FALSE;
    dwTemp=0;
    while(dwNumber>99999)
    {
          dwTemp+=1;
          dwNumber-=100000;
    }
    if((dwTemp>1)&&(IsDiv[dwTemp-2]==FALSE))
    return FALSE;
    dwTemp=0;
    while(dwNumber>9999)
    {
         dwTemp+=1;
        dwNumber-=10000;
    }
    if((dwTemp>1)&&(IsDiv[dwTemp-2]==FALSE))
    return FALSE;
    dwTemp=0;
    while(dwNumber>999)
    {
         dwTemp+=1;
         dwNumber-=1000;
    }
    if((dwTemp>1)&&(IsDiv[dwTemp-2]==FALSE))
    return FALSE;
    dwTemp=0;
    while(dwNumber>99)
    {
         dwTemp+=1;
         dwNumber-=100;
    }
    if((dwTemp>1)&&(IsDiv[dwTemp-2]==FALSE))
    return FALSE;
    dwTemp=0;
    while(dwNumber>9)
    {
         dwTemp+=1;
         dwNumber-=10;
    }
    if((dwTemp>1)&&(IsDiv[dwTemp-2]==FALSE))
    return FALSE;
    if((dwNumber>1)&&(IsDiv[dwNumber-2]==FALSE))
    return FALSE;
    return TRUE;
}
Вопрос - ответ
Выпуск #1
1. В нескольких программах видел, что при нажатии на пункт меню он становился выделенным
галочкой, а при повторном нажатии это выделение пропадало. Как мне это сделать в своей
программе ?
procedure TForm1.mnuFileClick(Sender: TObject); begin If mnuFile.Checked = False Then Begin mnuFile.Checked:=True; ShowMessage('Пункт меню отмечен !!!'); End Else If mnuFile.Checked = True Then Begin mnuFile.Checked:=False; ShowMessage('Пункт меню не отмечен !!!'); End; end; |
2. Как вывести текст поверх картинки загруженной в Image ?
procedure TForm1.FormCreate(Sender: TObject); Var BMP : TBitmap; begin BMP:=TBitmap.Create; BMP.LoadFromFile('MyPicture.bmp'); Image1.Picture.Assign(BMP); Image1.Canvas.Brush.Color:=clBlue; Image1.Canvas.Font.Name:='Arial'; Image1.Canvas.Font.Size:=10; Image1.Canvas.TextOut(10, 10, 'Некоторый текст !!!'); end; |
3. При выполнении большого цикла мое приложение как бы замирает. Можно ли это как-то исправить ?
Для этого нужно в тело цикла вставить конструкцию Application.ProcessMessages. При этом можно будет нажимать на различные кнопки, пользоваться меню, но нельзя будет закрыть приложение :(.
procedure TForm1.Button1Click(Sender: TObject); Var I: Integer; begin For I:=1 To 100000 Do Begin Label1.Caption:=IntToStr(I); Application.ProcessMessages; End; end; |
4. При удалении записи в БД выдается запрос на английском языке, хотя вся моя программа построена
на русском языке. Можно ли как-нибудь сделать этот запрос русским ?
Я тоже столкнулся с такой неприятной мелочью. Лично мне пришла в голову одна очень простая мысль: я сделал отдельный пункт меню "Удалить запись", в котором я написал свой обработчик удаления записи из набора данных с русским диалоговым запросом. Далее я задал свойству пункта меню ShortCut (быстрый доступ "горячей клавишей") значение Ctrl+Del. Еще можно просто запретить вывод запроса на удаление путем установки значения False подсвойству dgComfirmDelete свойства сетки DBGrig, но это не очень хорошо, потому что можно и не заметить как запись будет удалена. Вот небольшой и понятный пример:
procedure TForm1.mnuDBDelClick(Sender: TObject); begin If Application.MessageBox('Удалить запись ?', 'Удаление:', MB_YESNO) = idYES Then Table1.Delete; end; |
5. Как написать свой ScreenSaver ?
Честно говоря, я даже никогда об этом не задумывался :). По сути ScreenSaver - это обычная программа переименованная в расширение .scr. Даже если Вы любую программу переименуете из .exe в .scr, и поместите в каталог Windows или Windows\System, то через установленный промежуток времени переименованная программа сработает как ScreenSaver. Значит нужно написать свою собственную программу и в обработчики нажатия клавиш onKeyPress, onKeyDown и onKeyUp записать код закрытия программы. Аналогичным образом нужно "оформить" обработчики движения мыши. А еще надо проверять, чтобы программа запускалась в одном экземпляре, иначе таких хранителей экрана будет одновременно запущено сразу несколько :).
6. Во многих программах выдаются диалоги для ввода некоторых значений, например, пароля.
А как это делается, неужели создается отдельная форма ?
Для этого, безусловно, можно создать отдельную форму, но проще будет воспользоваться функциями InputBox или InputQuery. В своих программах с БД я частенько использую такой прием для перехода к определенной записи. Вот небольшой и понятный пример:
procedure TForm1.mnuDBGotoClick(Sender: TObject); Var Go: String; begin Go:='1'; InputQuery('Переход к записи', 'Перейти к записи с номером:', Go); Try If NOT Table1.Locate('Code', Go, []) Then MessageDlg('Запись с номером' + Go + 'не найдена', mtWarning, [mbOK], 0); Except MessageDlg('Значение' + Go + 'не допустимо', mtWarning, [mbOK], 0); End; end; |
7. При вводе текста в Memo и достижении правого края контрола текст автоматически переносится
на новую строку. Как с этим бороться ?
Для этого можно поступить двумя способами:
1) Установить свойству WordWrap значение False.
2) Установить свойству ScrollBars значение ssHorizontal - для появления горизонтальной полосы
прокрутки, или ssBoth - для появления обоих полос прокрутки.
8. Как можно программно управлять открытием и закрытием компонента ComboBox и узнать его
состояние в текущий момент ?
procedure TForm1.Button1Click(Sender: TObject); begin //Открываем список ComboBox1.DroppedDown:=True; end; procedure TForm1.Button2Click(Sender: TObject); begin //Закрываем список ComboBox1.DroppedDown:=False; end; procedure TForm1.Bla-Bla-Bla(Sender: TObject); begin If ComboBox1.DroppedDown = True Then ShowMessage('Список открыт') Else ShowMessage('Список закрыт') end; |
9. В программе 1С я заметил, что при редактировании ячейки БД в правой ее части появляется кнопка с тремя точками. Если нажать эту кнопку, то появляется отдельная форма для выбора товара. А можно ли такое сделать в Делфи ?
Конечно можно, для этого нужно воспользоваться т.н. статическими полями (о них я рассказывал в одной из статей о БД). Для определенного статического поля нужно установить свойство ButtonStyle в значение cbsEllipsis. А затем обрабатывать событие onEditButtonClick сетки DBDrid.
procedure TForm1.DBGrid1EditButtonClick(Sender: TObject); begin FormAdd2.ShowModal; end; |
10. Как программно создать компонент и навесить на него обработчик события?
uses ..., StdCtrls; ... procedure TForm1.FormCreate(Sender: TObject); Var Memo1 : TMemo; begin Memo1:=TMemo.Create(Self); Memo1.Parent:=Form1; Memo1.Top:=10; Memo1.Left:=10; Memo1.Height:=90; Memo1.Width:=150; Memo1.OnKeyPress:=MyMemoKeyPress; end; procedure TForm1.MyMemoKeyPress(Sender: TObject; var Key: Char); begin If NOT(Key In ['0'..'9', Chr(8), Chr(32)]) Then Key:=Chr(0); end; |
11. Можно ли в процессе выполнения программы узнать какой разделитель целой и дробной
части установлен в системе в данный момент, а то эти ошибки уже задолбали ?
Разделитель в своей программе можно задать свой. А так для этого служит DecimalSeparator.
procedure TForm1Main.FormCreate(Sender: TObject); begin DecimalSeparator:='.'; end; procedure TForm1.Button1Click(Sender: TObject); begin ShowMessage('Текущий разделитель: ' + DecimalSeparator); Edit1.Text:='10' + DecimalSeparator + '5'; end; |
12. Как установить курсор мыши в определенную позицию экрана ?
procedure TForm1.Button1Click(Sender: TObject); Var P: TPoint; begin GetCursorPos(P); // Сохраняем позицию курсора ... // Что-то делаем ... SetCursorPos(P.X, P.Y); // Восстанавливаем позицию курсора end; |
13. Хочу при запуске программы сделать кнопку активной, но постоянно выдается ошибка.
Как лечить ?
Если уже Вы решили сделать кнопку активной в обработчике события создания формы, то нужно просто вставить обработчик исключительной ситуации, которая как раз и генерируется. Но при компиляции проекта это исключение все равно будет возникать, что очень не удобно. Более простым и удобным способом будет использовать событие формы onShow. Тогда уж точно никаких ошибок не возникнет.
procedure TForm1.FormCreate(Sender: TObject); begin Try If Button1.CanFocus Then Button1.SetFocus; Except End; end; procedure TForm1.FormShow(Sender: TObject); begin If Button1.CanFocus Then Button1.SetFocus; end; |
14. Как из моей программы некоторый файл сделать скрытым ?
Для этого ему нужно задать атрибут как "скрытый".
procedure TForm1.FormCreate(Sender: TObject); begin SetFileAttributes('File.txt', FILE_ATTRIBUTE_HIDDEN); end; |
15. Где можно взять архивы и учебники по Delphi?
Самый оптимальный вариант изучения любого языка программирования - это хорошая книга, электронные источники и исходники. Я конечно не уверен, может быть некоторые ссылки уже умерли, но все же...
P.S.: Для уменьшения объема рассылки все вопросы были отредактированы !!!
Любые комментарии, жалобы, пожелания и сообщения об ошибках настоятельная просьба присылать на e-mail.
Статьи
В очередной своей работе я хочу рассказать о DDE - Dynamic Data Exchange, то есть о динамическом обмене данными между приложениями. Начав изучать тему DDE, я понял, что это как-то похоже на чат. Принцип работы с DDE - это технология Клиент-Сервер. Delphi позволяет создавать как сервер, так и клиент. Все компоненты для организации технологии DDE находятся на странице System Палитры компонентов. Сразу хочу отметить, что при использовании DDE возникает множество проблем, которые будут оговорены далее. Приложение Сервера: Для начала попробуем создать приложение сервера. Для этого нужно создать новый проект. Затем положить на форму стандартные и специальные компоненты присущие Серверу:
Компонент TDdeServerConv представляет собой сеанс передачи данных, а компонент TDdeServerItem
- сами передаваемые данные. Обычно приложение Сервера содержит один компонент TDdeServerConv и
несколько компонентов TDdeServerItem. Эти компоненты используются совместно. Через свойство
ServerConv компонент TDdeServerItem связывается с TDdeServerConv.
Так как TDdeServerItem содержит сами передаваемые данные, то эти данные должны где-то содержаться. Все данные заносятся в два основных свойства: Lines - для передачи сразу нескольких строк и Text - для передачи одной строки. Как только одно из этих свойств изменяться, они сразу же передаются приложению Клиента.
Для того чтобы организовать соединение Клиента с Сервером, Клиенту нужно знать все параметры Сервера.
Для этого нужно использовать метод CopyToClipboard;
При получении данных от клиента нужно обрабатывать событие onPokeData. В нашем случае нужно
просто отобразить переданные данные на одном из компонентов TMemo.
А теперь рассмотрим наглядный пример приложения Сервера. Начнем с процедуры создания формы:
При получении данных от Клиента отображаемых их в одном из компонентов TMemo:
Кнопка для отправки сообщения Клиенту. При нажатии на кнопку происходи присвоение текста, введенного
в другой компонент TMemo и его немедленная отправка Клиенту:
Так как Сервер и Клиент используются совместно, то при закрытии одного из них второй так и останется
запущенным. Для этого при закрытии приложения Сервера закрываем и приложение Клиента:
Trouble № 1: Мною была замечена одна очень не приятная вещь. Приложение
Сервера без проблем принимает многострочные данные от Клиента, а в свою очередь Клиент не "хочет"
принимать многострочные данных от Сервера. Именно поэтому я решил запретить нажатие клавиши Enter,
чтобы хоть как-то скрыть этот огромный недостаток.
Приложение Клиента: Теперь попробуем создать приложение Клиента. Клиент предназначен для получения данных от приложения Сервера. Теоретически Клиентов может быть несколько. Создадим новый проект. Затем положить на форму стандартные и специальные компоненты присущие Клиенту:
Компонент TDdeClientConv также представляет собой сеанс передачи данных, а компонент
TDdeClientItem - сами передаваемые данные, которые также хранятся в свойствах Lines
- для отправки нескольких строк и Text - для отправки одной строки. Обычно приложение
клиента также содержит один компонент TDdeClientConv и несколько компонентов TDdeClientItem.
Эти компоненты используются совместно. Через свойство DdeConv компонент TDdeClientItem
связывается с компонентом TDdeClientConv. А через свойство DdeItem задается источник данных.
Для организации параметров соединения используются следующие свойства:
Имя Сервера принято указывать без расширения, хотя даже если и указать расширение, то это не вызовет ни какой ошибки.
Trouble № 2: Установить перечисленные свойства динамически, то есть
во время выполнения программы, скорее всего не получиться. Все эти команды будут просто игнорированы.
Это нужно делать на этапе конструирования формы через Инспектор объектов.
При установки свойств через Инспектор объектов нужно воспользоваться одним из свойств компонента TDdeClientConv: DdeService или DdeTopic. При этом заполнение полей одного свойства приведет к заполнению полей другого свойства. Также можно нажать кнопку "Paste Link", что приведет к автоматическому заполнению полей. Но, эта кнопка будет активна только в том случае, если приложение Сервера было хоть раз запущено ранее, то есть "сработал" метод CopyToClipboard. При помощи свойства ConnectMode можно управлять способ подключения к Серверу. Если это свойство установлено в ddeAutomatic, то подключение осуществляется автоматически, а если свойство установлено в ddeManual, то подключение осуществляется вручную и для нормальной работы приложения программисту придется самому описывать все операторы. Для этого нужно воспользоваться группой операторов SetLink, OpenLink, CloseLink и RequestData. Для того чтобы отправить текстовое сообщение на Сервер существуют две основные функции PokeData - для отправки на Сервер однострочных данных и функция PokeDataLines для отправки многострочных данных.
А теперь рассмотрим наглядный пример приложения Клиента. Начнем с процедуры создания формы:
Кнопка для отправки данных на Сервер. Данные отправляются двумя различными способами. При
отправке данных первым способ используется функция Trim для удаления не нужных пробелов,
потому что при получении данных эти пробелы могут быть интерпретированы как кавычки или любые
другие символы:
Процедура для отображения полученных данных от Сервера:
При закрытии приложения Клиента также закрываем и приложение Сервера:
Здесь также запрещаем использовании клавиши Enter:
В процессе написания и отладки программы иногда необходимо узнать некоторые данные о соединении.
Так, например, можно узнать имя Сервера:
А так можно узнать тему обмена данными и DdeServerItem:
Посредством DDE так же можно управлять и некоторыми приложениями, например, такими как MS Office, но как это делается я пока не знаю, и как только научусь, то обязательно об этом напишу свою очередную работу. Если кто-нибудь из Вас обладает какой-либо информацией по этому поводу, то поделитесь, пожалуйста, буду весьма признателен. Любые комментарии, жалобы, пожелания и сообщения об ошибках настоятельная просьба присылать на e-mail. |
Хочу Вам честно признаться, что обожаю видеть на своем Рабочем столе не только упорядоченные иконки программ, но и красивую картинку. Каждая картинка у меня задерживается не более чем на одну неделю. И вот как-то вечером сменив, вручную, очередную картинку Рабочего стола я решил написать для этого специальную программу. Почитав несколько статей, найденных в глобальной сети, я нашел необходимую информацию и приступил к работе. И вот что из этого получилось. Для начала нужно создать новый проект. Затем положить на форму следующие стандартные компоненты:
Информация о картинке Рабочего стола находиться в системном реестре по адресу:
HKEY_CURRENT_USER\Control Panel\Desktop. Имя картинки содержится в параметре
WallPaper, а информация о положении картинки располагается в параметрах TileWallpaper
и WallPaperStyle. Вот список соответствующих значений:
И начнем мы с процедуры для автозапуска программы при старте Windows. Для этого по соответствующему
адресу системного реестра занесем имя программы и ее путь: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run
Процедура для задания необычного фона, который берется из картинки. Если файл был умышленно
удален, то программа не будет загружена:
В процедура создания формы мы вызываем процедуру автозапуска программы, задаем форме нестандартный
вид, считываем значение пути к графическим файлам и производим их поиск и загрузку в список:
Так как форма не содержит заголовка, то делаем возможность перетаскивания формы за любое
место, а не только за заголовок:
Кнопка "Открыть". При нажатии на кнопку происходит заполнение списка файлов, и путь к этим файлам
автоматически сохраняется в файл инициализации:
Кнопка для указания параметра "По центру":
Кнопка для указания параметра "Растянуть":
Кнопка для указания параметра "Рядом":
Главная процедура для указания картинки Рабочего стола и положения картинки:
Процедура для навигации по списку файлов. Если текущая строка списка находиться во включенном
состоянии, то соответствующая картинка и ее путь будут отображены, если же она находиться в
выключенном состоянии, то картинка и ее путь отображена не будет:
Процедура для очистки списка файлов:
Кнопка для навигации по списку файлов вперед:
Кнопка для навигации по списку файлов назад:
При выходе из программы сохраняем последний указанный путь к графическим файлам:
P.S.: Если кто-нибудь из Вас знает как в Delphi работать с графическими файлами любых других форматов, то напишите мне, пожалуйста, или поделитесь ссылочкой. Буду весьма признателен. Любые комментарии, жалобы, пожелания и сообщения об ошибках настоятельная просьба присылать на e-mail. |
Все вопросы, пожелания и предложения ссылкообмена ведущему рассылки, прошу слать на e-mail: urisff@inbox.ru
Все статьи публикуются здесь только с разрешения (или рекомендации) автора.
Если вы хотите опубликовать здесь свою статью, то сделайте это, переслав её мне.
В случае, если вы будете использовать приведённые в этой рассылке материалы, не забудьте сделать ссылку на эту рассылку.
Ведущий рассылки:
Набатников Иван
urisff@inbox.ru
http://WWW.URiS.TK
http://subscribe.ru/
E-mail: ask@subscribe.ru |
Отписаться
Убрать рекламу |
В избранное | ||