Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» Вопросы по Delphi (до версии 2009) - часть 6

Автор: ShIvADeSt
Дата сообщения: 19.05.2010 04:13
Продолжение темы Вопросы по Delphi (до версии 2009) - часть 5

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

Правила топика:
Прежде чем спрашивать:
Желательно изучить вопрос, попытаться найти ответ в прилагаемых мануалах, хелпах и анализируя исходники.
Выполнить поиск по топику (открыть "Версия для печати" и поискать ответ там).
Применить фильтр по разделу "Прикладное программирование". Ответы на многие старые вопросы могли быть даны в отдельных темах.
Продумайте вопрос. На поверхностные вопросы вы получите поверхностные ответы, или вообще ответов не получите.
Желательно указывать версии используемого компилятора и операционной системы.
Прежде чем отвечать:
Если не можете помочь, не мешайте.
Если уж вы отвечаете на вопрос, давайте ответ по сути.
Если вы не уверены, так и говорите! Ошибочный, но авторитетно звучащий ответ хуже, чем отсутствие ответа.
Задавайте дополнительные вопросы, чтобы получить больше информации.
Отсутствие ответа не равносильно игнорированию - иногда участники форума просто не знают ответ. Повторная посылка вопроса не приветствуется. Посты типа "неужели никто не знает ответа..." или "может мне все-таки кто-нибудь ответит" недопустимы.
Все большие куски кода (более 5 строк) оформляем в тег [morе] дабы уменьшить размер поста. FAQ по тегу [morе].
Некоторые "родственные" топики:
Вопросы по Delphi (версии 2009-2010 Weaver)
Вопросы по компонентам для Delphi, C++ Builder
Использование DevExpress
Вопросы по Ehlib
Компоненты и утилиты для Delphi/BCB/FreePascal/Lazarus - только Open Source
Коммерческие компоненты и утилиты для Delphi/BCB
Прикладное программирование и не только...
См. также: [more=Некоторые полезные ресурсы о Delphi]
Королевство Delphi
DRKB (Delphi Russian Knowledge Base) & DRKB Explorer
Torry's Delphi Pages
Pascal.Sources.Ru - Паскальные исходники со всего света
Delphi Plus - ежедневные новости информационных технологий[/more]


И старайтесь, чтобы ваш код не попал сюда
Автор: Bonivur
Дата сообщения: 19.05.2010 10:24
Odysseos
Frodo_Torbins
С помощью TntUnicode Controls проблему решил. Все юникод символы сохраняются. Спасибо. Посмотрите, не слишком ли корявый код определения кодировки -

Код:
const
UTF8 = #$EF#$BB#$BF;
UTF16LE = #$FF#$FE;
UTF16BE = #$FE#$FF;
var
temp_str:string;
f : TextFile;
begin
if OpenDlg.Execute then
begin
Memo.Lines.LoadFromFile(OpenDlg.FileName);

AssignFile(f,OpenDlg.FileName);
{$I-}
Reset(f);
{$I+}
If IOResult=0 then
begin
try
ReadLn(f,temp_str);
finally
CloseFile(f);
end;
end;

if (temp_str[1]+temp_str[2]+temp_str[3]<>UTF8) and (temp_str[1]+temp_str[2]<>UTF16LE)
and (temp_str[1]+temp_str[2]<>UTF16BE) then ShowMessage('Unicode') else ShowMessage('Non-Unicode');

Автор: EugeneBoss3
Дата сообщения: 21.05.2010 02:45
Коллеги, не подскажете, где можно посмотреть или как реализовать выпадающий список TPopupListBox = class(TCustomListBox) - не PopupMenu, а именно список по нажатию кнопки. В нете ничего нужного не нашел. Заранее спасибо.
Автор: ShIvADeSt
Дата сообщения: 21.05.2010 03:39
Bonivur

Цитата:
Посмотрите, не слишком ли корявый код определения кодировки

А если при помощи этого IsTextUnicode
Автор: Bonivur
Дата сообщения: 21.05.2010 10:15
ShIvADeSt
Я пробовал (ради эксперимента), но что-то не смог прикрутить, но мне по любому надо определение кодировки не текста, а файла.
Автор: Maks150988
Дата сообщения: 23.05.2010 21:11
Bonivur
Ну типа так я делал.
[more=>>]


Код: unit F_StrUtils;

interface

uses
Windows;

{function Is_US_ASCII_Ansi(Buf: Pointer; Size: Integer): Boolean;}
{function Is_US_ASCII_Wide(Buf: Pointer; Size: Integer): Boolean;}

function Is_UTF_8_BOM(Buf: Pointer; Size: Integer): Boolean; // utf-8
function Is_UTF_16_BE_BOM(Buf: Pointer; Size: Integer): Boolean; // unicode
function Is_UTF_16_LE_BOM(Buf: Pointer; Size: Integer): Boolean; // bigendian

function SwapUTF16Endian(P: WideChar): WideChar;
function UTF8ToStrSmart(s: AnsiString): AnsiString;

implementation

{function Is_US_ASCII_Ansi(Buf: Pointer; Size: Integer): Boolean;
var
I: Integer;
P: PAnsiChar;
begin
P := Buf;
for I := 1 to Size do
if (Ord(P^) >= $80) then
begin
Result := FALSE;
Exit;
end
else
Inc(P);
Result := TRUE;
end;}

{function Is_US_ASCII_Wide(Buf: Pointer; Size: Integer): Boolean;
var
I: Integer;
P: PWideChar;
begin
P := Buf;
for I := 1 to Size do
if (Ord(P^) >= $80) then
begin
Result := FALSE;
Exit;
end
else
Inc(P);
Result := TRUE;
end;}

function Is_UTF_8_BOM(Buf: Pointer; Size: Integer): Boolean;
var
Q: PAnsiChar;
P: PAnsiChar;
begin
Result := FALSE;
P := PAnsiChar(Buf);
if Assigned(P) and (Size >= 3) and (P^ = #$EF)
then
begin
Q := P;
Inc(Q);
if (Q^ = #$BB) then
begin
Inc(Q);
if (Q^ = #$BF) then
Result := TRUE;
end;
end;
end;

function Is_UTF_16_BE_BOM(Buf: Pointer; Size: Integer): Boolean;
var
P: PAnsiChar;
begin
P := PAnsiChar(Buf);
Result := Assigned(P) and (Size >= Sizeof(WideChar)) and (PWideChar(P)^ = WideChar($FEFF));
end;

function Is_UTF_16_LE_BOM(Buf: Pointer; Size: Integer): Boolean;
var
P: PAnsiChar;
begin
P := PAnsiChar(Buf);
Result := Assigned(P) and (Size >= Sizeof(WideChar)) and (PWideChar(P)^ = WideChar($FFFE));
end;

function SwapUTF16Endian(P: WideChar): WideChar;
begin
Result := WideChar(((Ord(P) and $FF) shl 8) or (Ord(P) shr 8));
end;

function UTF8ToStrSmart(s: AnsiString): AnsiString;
var
str: AnsiString;
idx: Integer;
hex: Byte;
cln: Byte;
buf: Pointer;
len: Integer;
begin
Result := '';
cln := 0;
if (s = '') then
Exit;
for idx := 1 to Length(s) do
begin
if (cln > 0) then
begin
str := str + s[idx];
Dec(cln);
if (cln = 0) then
begin
len := Length(str) + 4;
GetMem(buf, len);
ZeroMemory(buf, len);
MultiByteToWideChar(CP_UTF8, 0, @str[1], len - 4, buf, len);
Result := Result + WideCharToString(buf);
FreeMem(buf, len);
end;
end
else
begin
hex := Ord(s[idx]);
if hex in [$00..$7F] then // Standart ASCII chars
Result := Result + s[idx]
else
begin
// Get lgth of UTF-8 char
if hex and $FC = $FC then
cln := 6
else
if hex and $F8 = $F8 then
cln := 5
else
if hex and $F0 = $F0 then
cln := 4
else
if hex and $E0 = $E0 then
cln := 3
else
if hex and $C0 = $C0 then
cln := 2
else
begin
Result := Result + s[idx];
Continue;
end;
Dec(cln);
str := s[idx];
end;
end;
end;
end;

end.
Автор: Bonivur
Дата сообщения: 24.05.2010 09:38
Maks150988
Спасибо, но мне это уж слишком громоздкий код для моей задачи. Открываем файл через OpenDialog. Помещаем его в Memo. Нужно определить кодировку открытого файла. Мой код, который я привел выше работает хорошо (я проверял на всех типах Unicode и ASCII текста). Более того, в связке с модулем XLat.pas компонент Memo правильно определяет и выводит текст в кодировках - DOS, KOI-8, Win1251, UTF-8, UTF16LE и BE, что мне, в принципе, и надо. Единственное, в чем я сомневался будет ли код определять ВСЕ Unicode файлы. Возможно это у меня для тестирования попались "удобные" образцы. То есть является мой код fool-proof?
А зачем Вам понадобилось идти столь сложным путем? Почему нельзя было использовать AssignFile и далее читать строки через ReadLn на наличие символов Юникода?
Автор: Maks150988
Дата сообщения: 24.05.2010 11:48
Bonivur
Если честно, то мне тогда надо было просто отобразить весь текст, сам блокнот по такому принципу и работает. Да и привычнее апи функциями уже орудовать.
Автор: Man_Without_Face
Дата сообщения: 25.05.2010 08:10
Есть DLL с отчетами (FastReport v4.8) разработанная на CodeGear2009. Экзешник (Delphi 5) нормально вызывает отчет, но когда пытаешься свернуть программу с запущенным отчетом она разворачивается обратно. Вопрос: можно ли это исправить (в DLL или в настройках отчетов)? Отчеты вызываются НЕ модально.


Автор: Frodo_Torbins
Дата сообщения: 25.05.2010 10:14
Man_Without_Face
Application.Handle вы своей длл-ке передаете?
Автор: 0z0n
Дата сообщения: 25.05.2010 10:47
Помогите с таким вопросом замахался не могу сделать простого, может кто знает как:
Мне надо чтобы в зависимости от включения и выключение кнопки менялись ее надписи.
Вот чего я наваял. Может офтоп извините...

procedure TSDIAppForm.BitBtn1Click(Sender: TObject);
begin
if BitBtn1.Caption = 'START' then (BitBtn1.Caption := 'STOP');
if BitBtn1.Caption = 'STOP' then (BitBtn1.Caption := 'START');
end;

Заранее благодарен.
Автор: Frodo_Torbins
Дата сообщения: 25.05.2010 11:04
0z0n
Ключевое слово "else" применять не пробовали?
Автор: mdid
Дата сообщения: 25.05.2010 12:32
0z0n
лучше не привязываться к надписям..ибо не та буква или не тот ригистр символа и условие не выполнится...
проще вязать к BitBtn1.tag...тоесть

Код:
procedure TSDIAppForm.BitBtn1Click(Sender: TObject);
begin
if BitBtn1.Tag =0 then begin//было выключено - включили
BitBtn1.Caption := 'STOP';
BitBtn1.tag := 1;
end
else begin//было включено-выключили
BitBtn1.Caption := 'START';
BitBtn1.tag := 0;
end
Автор: Man_Without_Face
Дата сообщения: 25.05.2010 13:58
Frodo_Torbins
Да, handle передаю
Автор: 0z0n
Дата сообщения: 25.05.2010 14:08
Еще вопрос у меня куча значений в формах. Как и где лучше всего их хранить. Мое мнение в каком то текстовом файле типа файла конфигурации. Программа для обработки данных с com порта и контроля контролера зерносушилки. Мне надо где то хранить предельные обороты двигателей которые указывает пользователь. Предельные температуры горелок. И в камерах и т. д. подскажите, а то я дуб дерево. Мне все хотелось бы сгрузить в несколько файликов и как то их закодировать чтобы пользователь не смог редактировать. Пасиб.
Автор: mdid
Дата сообщения: 25.05.2010 14:15
0z0n
dbf,ini,mdb(придется на access расчитывать)...можно даже в открытом виде в текством файле..но зиповать его...если данных много то советовал бы все таки sql базу
Автор: 0z0n
Дата сообщения: 25.05.2010 15:26
mdid
А Если в текстовый файл то какая компонента?
Автор: mdid
Дата сообщения: 25.05.2010 15:34
0z0n
текстовый файл это плохой вариат...ибо придется делать свою структуру для записи и чтения
еси все таки этот вариант то хелп в сторону функций
AssignFile
Reset
или через FileStream..но все это откровенно говоря дерьмовый вариант
в так же бесплатный компонент зиповки zipforge
и еси уже решили делать через файлы то проще через ini тогда
Автор: 0z0n
Дата сообщения: 25.05.2010 16:24
А проще хранить какую то таблицу в структуре базы данных в которой хранить все свои опции? Я чесно не до конца соображаю как это сделать. Короче торба.
Автор: mdid
Дата сообщения: 25.05.2010 16:31
0z0n
вы не обижайтесь но судя по вопросу ваш опыт delphi не более 2-3 часов...вряд ли вы осилите на таком уровне знаний работу еще и с портом и тд...начтните с азов..или пусть предприятие выделить денюжку на опытного программера..так как за вас каждый шаг тут никто делать не будет
Автор: 0z0n
Дата сообщения: 25.05.2010 16:42
Ок. Согласен книжки есть. Буду читать.
Автор: StalkerSoftware
Дата сообщения: 26.05.2010 17:19
Hi All,

Delphi 7.1, WinXP SP3 Rus, раскладка клавиатуры по умолчанию "Английская".

Делаю новый проект, и в его обработчик OnCreate помещаю такой код:

Код:
var
FOldLayout :Array [0..KL_NAMELENGTH] of Char;

GetKeyboardLayoutName(FOldLayout);
ShowMessage(FOldLayout);
Автор: volser
Дата сообщения: 26.05.2010 17:33
StalkerSoftware
Что такое текущая раскладка? Для какого приложения? Для каждого приложения своя текущая раскладка.
Автор: AviDen
Дата сообщения: 26.05.2010 18:04
StalkerSoftware, потому что сразу же после создания процесса текущей для него устанавливается раскладка по умолчанию.
Автор: StalkerSoftware
Дата сообщения: 26.05.2010 19:42
volser

Цитата:
Что такое текущая раскладка?
Это та раскладка, которую выбрал пользователь текущий момент времени в языковой панели (которая возле трея).


Цитата:
Для каждого приложения своя текущая раскладка.
А нет ли некой глобальной текущей раскладки в винде ?

AviDen

Цитата:
потому что сразу же после создания процесса текущей для него устанавливается раскладка по умолчанию.
А эту фичу ни как нельзя отключить для своего приложения ?

В общем то вопрос этот возник по следующей причине:

Набирает скажем пользователь в ворде текст на русском языке. Захотелось ему запустить мою программу и набрать некоторые данные там.
Для запуска моей программы ему нужно ввести пароль на английском языке. Для того, что бы уменьшить вероятность неправильного ввода пароля, я в окне запроса пароля перед его появлением хочу сохранить ту раскладку клавиатуры, которая была до запуска этого окна (до запуска моей программы), а после закрытия окна с паролем вернуть сохраненную раскладку.

Соответственно я рассчитывал, что GetKeyboardLayoutName мне в этом и поможет - вернет текущую раскладку (до запуска моего приложения).

Можно ли все же сделать то, что я описал выше (в причине) или нет ?


Автор: Frodo_Torbins
Дата сообщения: 26.05.2010 20:23
StalkerSoftware
Можно перед созданием своих окон получить текущее активное окно. И потом попробовать узнать его раскладку.
Правда это будет не совсем стандартное поведение, понравится ли пользователю?
Автор: psa1974
Дата сообщения: 26.05.2010 21:41
StalkerSoftware
Я в своей проге делал так: при запуске устанавливаю программно принудительно русскую раскладку, ибо все данные в проге вводятся в русской раскладке. Если юзер вызывает диалог ввода логина/пароля - запоминаю на всякий текущую раскладку и принудительно меняю раскладку на ангельский язык, показываю диалог, после ввода логина/пароля и закрытия диалога возвращаю раскладку, которую запомнил. Юзеры все просто счасливы
[more=пример]
Код: function GetLayout(asWinNT: Boolean): string;
begin
case LoWord(GetKeyboardLayout(0)) of
1033: Result:= 'En';
1049: Result:= 'Ru';
1058: Result:= 'Uk'
else
Result:= '??';
end;
if asWinNT then
Result:= UpperCase(Result);
end;

procedure SetLayout(fLayout: string);
var
Layout : array[0..KL_NAMELENGTH] of Char;
LayoutHKL: HKL;
begin
fLayout:= AnsiLowerCase(fLayout);
if (fLayout = 'ru') then
StrCopy(Layout, '00000419') // 00000419 - русская раскладка
else
if (fLayout = 'en') then
StrCopy(Layout, '00000409') // 00000419 - английская раскладка
else
if (fLayout = 'uk') then
StrCopy(Layout, '00000422') // 00000422 - украинская раскладка
else
Exit;
LayoutHKL:= LoadKeyboardLayout(Layout, 0);
ActivateKeyboardLayout(LayoutHKL, KLF_ACTIVATE);
PostMessage(Application.Handle, WM_INPUTLANGCHANGEREQUEST, 1, LayoutHKL);
end;

procedure SetEngLayout;
var
Layout : array[0..KL_NAMELENGTH] of Char;
LayoutHKL: HKL;
begin
StrCopy(Layout, '00000409'); // 00000419 - английская раскладка
LayoutHKL:= LoadKeyboardLayout(Layout, 0);
ActivateKeyboardLayout(LayoutHKL, KLF_ACTIVATE);
PostMessage(Application.Handle, WM_INPUTLANGCHANGEREQUEST, 1, LayoutHKL);
end;

procedure TMainFrm.Button1Click(Sender: TObject);
var fLayout: string;
begin
fLayout:= GetLayout(True);
SetEngLayout;
try
// тут показываю модальный диалог воода логина/пароля
// бла-бла-бла, типо обработка полученного логина/пароля
finally
SetLayout(fLayout);
end;
end;
Автор: Bonivur
Дата сообщения: 26.05.2010 21:47
StalkerSoftware

Просто поменяйте код...

begin

if GetKeyboardLayout(GetWindowThreadProcessId(GetForegroundWindow, nil)) = 67699721 then
ShowMessage('English')
else
ShowMessage('Russian');
end;
Автор: mdid
Дата сообщения: 27.05.2010 07:54
StalkerSoftware
мне кажется это лишнее...у меня во всех прогах окно авторизации показывает в Label раскладку клавы выделенную синим цветом с увеличенный шрифтом...на фоне черных букв остальнных данных эти данные выделяются...так что как по мне то вы себе лишнюю работу придумали
Автор: AviDen
Дата сообщения: 27.05.2010 10:38
StalkerSoftware
Цитата:
Набирает скажем пользователь в ворде текст на русском языке. Захотелось ему запустить мою программу и набрать некоторые данные там.
Для запуска моей программы ему нужно ввести пароль на английском языке. Для того, что бы уменьшить вероятность неправильного ввода пароля, я в окне запроса пароля перед его появлением хочу сохранить ту раскладку клавиатуры, которая была до запуска этого окна (до запуска моей программы), а после закрытия окна с паролем вернуть сохраненную раскладку.

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

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374

Предыдущая тема: MPO File


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.