Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2006.08.20;
Скачать: [xml.tar.bz2];

Вниз

Баги при спользовании иконок в Области уведомления(systray)   Найти похожие ветки 

 
EvilIJ ©   (2006-04-21 13:56) [0]

Ребята, подскажите кто-н:
Создал компонент TIJTrayIcon, все работает замечательно и на много быстрее чем скажем TCoolTrayIcon, т.к. я не ломаю свой app во время выполнения программы, а использую WinApi. Все это хорошо, но при выключении компьютера (ENDSESSION) или при смене пользователя, моя прога не дает компу выключиться.
Я поковырял коды, отловил QUERY- и END- SESSION, программу выключаю, а винда все равно не тухнет :( . Пробывал даже рабочему столу эти сообщения посылать - тщетно. Что делать?
Как ПРАВИЛЬНО все завершить? Заранее, спасибо.


 
Юрий Зотов ©   (2006-04-21 14:29) [1]

Что отвечает компонент на сообщение WM_QUERYENDSESSION?


 
EvilIJ ©   (2006-04-21 15:55) [2]

В настоящее время компонент просто вызывает метод OnQueryEndSession и ничего в систему не отдает.
Я пока еще не проверял, но друзья говорят, что язабыл про PostQuitMessage(0) :), хотя, может и нет...

Кстати, у CoolTrayIcon та же проблема :)))))))))


 
Юрий Зотов ©   (2006-04-21 16:21) [3]

Чей метод OnQueryEndSession вызывает компонент? Как реализован этот метод?

Ничего не отдавать в систему невозможно. Даже если сообщение не обрабатывается, какой-то результат оно все равно имеет, пусть даже случайный. И в данном случае небезразлично, что это за результат.

Поэтому важно ТОЧНО знать, как он формируется. Нужны детали. Лучше всего - полный код компонента.


 
EvilIJ ©   (2006-04-24 08:43) [4]

Скорее всего, дело не в компоненте, а в программе его использующей...
С PostQuitMessage(0) та же бадяга... Хотя, если хочешь, мне не жаль компонента, я могу его тебе скинуть, только, пожалуйста, пообещай найти решение... (Напрягает вставлять halt внутрь компонента :))) )


 
EvilIJ ©   (2006-04-24 08:47) [5]

(Я не нашел твоего почт. ящика, поэтому скинь мне запросик на EvilIJ@mail.ru а я тебе отвечу посылкой с вложенным архивом)


 
Юрий Зотов ©   (2006-04-24 12:22) [6]

> EvilIJ ©   (24.04.06 08:43) [4]

> Скорее всего, дело не в компоненте, а в программе его использующей...
То есть, как раз в компоненте.

> мне не жаль компонента, я могу его тебе скинуть
Спасибо, мне он не нужен - но почему бы не выложить его здесь?

> только, пожалуйста, пообещай найти решение...
Его даже и искать не надо, оно и без поисков известно. Вопрос лишь в том, годен ли компонент для него в принципе своем - то есть, правильно ли он вообще спроектирован.


 
EvilIJ ©   (2006-04-24 12:37) [7]

Вопрос: как выложить компонент?
Если пасовский модуль кидаешь - говорят: слишком много символов.
PS Может почтой лучше?


 
Юрий Зотов ©   (2006-04-24 12:46) [8]

Разбейте код на несколько сообщений.


 
EvilIJ ©   (2006-04-24 12:48) [9]

unit IJTrayIcon;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
 ShellAPI,  menus;

const UWM_TRAYICON = WM_USER+1024;
{$WARN SYMBOL_DEPRECATED OFF}
type
 TIJTrayIcon = class(TComponent)
 private
   { Private declarations }
   FIcon: TIcon;
   FHint: TCaption;
   FShowHint: boolean;
   FLeftPopup: boolean;
   FPopupMenu: TPopupMenu;
   data:TNotifyIconData;
   FVisible: boolean;
   FOnClick,
   FOnDblClick,
   FOnEndSession,
   FOnQueryEndSession: TNotifyEvent;
   FOnMouseMove: TMouseMoveEvent;
   FOnMouseDown,
   FOnMouseUp: TMouseEvent;

   Procedure SetIcon(Value: TIcon);
   Procedure SetVisible(Value: boolean);
   Procedure SetHint(Value: TCaption);
   Procedure SetShowHint(Value: boolean);
   function GetClientIconPos(P: TPoint): TPoint;
   Procedure IconChanged(Sender: TObject);
 protected
   { Protected declarations }
   procedure Click; dynamic;
   procedure DblClick; dynamic;
   procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); dynamic;
   procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); dynamic;
   procedure MouseMove(Shift: TShiftState; X, Y: Integer); dynamic;
 public
   { Public declarations }
   procedure Show;
   procedure Hide;
   constructor Create(AOwner: TComponent); override;
   destructor Destroy; override;
   procedure TrayDefaultHandler (var Message:TMessage);
   procedure Refresh;
 published
   { Published declarations }
   property Icon: TIcon read FIcon write SetIcon stored true;
   property Visible: boolean read FVisible write SetVisible;
   property Hint: TCaption read FHint write SetHint;
   property ShowHint: boolean read FShowHint write SetShowHint;
   property LeftPopup: boolean read FLeftPopup write FLeftPopup;
   property OnClick: TNotifyEvent read FOnClick write FOnClick;
   property OnDblClick: TNotifyEvent read FOnDblClick write FOnDblClick;
   property OnMouseMove: TMouseMoveEvent read FOnMouseMove write FOnMouseMove;
   property OnMouseDown: TMouseEvent read FOnMouseDown write FOnMouseDown;
   property OnMouseUp: TMouseEvent read FOnMouseUp write FOnMouseUp;
   property OnEndSession: TNotifyEvent read FOnEndSession write FOnEndSession;
   property OnQueryEndSession: TNotifyEvent read FOnQueryEndSession write FOnQueryEndSession;
   property PopupMenu: TPopupMenu read FPopupMenu write FPopupMenu;
 end;


 
EvilIJ ©   (2006-04-24 12:48) [10]

procedure Register;

implementation

procedure Register;
begin
 RegisterComponents("IJ Components", [TIJTrayIcon]);
end;
//////////////////////////////////////////////////////////////////////////////////////////
constructor TIJTrayIcon.Create(AOwner: TComponent);
var H: THandle;
begin
 inherited Create(AOwner);
 FIcon:=TIcon.Create;

 if not(csDesigning in ComponentState) then
 begin
   H:=AllocateHWnd(TrayDefaultHandler);
   data.cbSize:=SizeOf (DATA);
   data.Wnd:=H;
   data.uCallbackMessage:=UWM_TRAYICON;
   data.uFlags:=NIF_ICON or NIF_TIP or NIF_MESSAGE;
   Icon:=Application.Icon;
 end;
end;
//////////////////////////////////////////////////////////////////////////////////////////
destructor TIJTrayIcon.Destroy;
begin
 Shell_NotifyIcon (NIM_DELETE,@data);
 FIcon.Free;
 inherited Destroy;
end;
//////////////////////////////////////////////////////////////////////////////////////////
procedure TIJTrayIcon.TrayDefaultHandler (var Message:TMessage);
var Pt, p: TPoint;
   Shift: TShiftState;
 function ShiftState: TShiftState;
 // Return the state of the shift, ctrl, and alt keys
 begin
   Result := [];
   if GetAsyncKeyState(VK_SHIFT) < 0 then
     Include(Result, ssShift);
   if GetAsyncKeyState(VK_CONTROL) < 0 then
     Include(Result, ssCtrl);
   if GetAsyncKeyState(VK_MENU) < 0 then
     Include(Result, ssAlt);
 end;
begin
if Message.Msg = WM_ENDSESSION then
 begin
   if Assigned(FOnEndSession) then
     FOnEndSession(Self);
 end;
if Message.Msg = WM_QUERYENDSESSION then
 begin
   if Assigned(FOnQueryEndSession) then
     FOnQueryEndSession(Self);
 end;
if Message.Msg=UWM_TRAYICON then
begin
 case Message.LParam of
   WM_LBUTTONDOWN:   begin
                       GetCursorPos(Pt);
                       Shift := ShiftState + [ssLeft];
                       p:=GetClientIconPos(pt);
                       MouseDown(mbLeft, Shift, p.X, p.Y);
                       if FLeftPopup then
                         if FPopupMenu<>nil then
                           FPopupMenu.Popup(pt.X, pt.Y);
                     end;
   WM_LBUTTONUP:     begin
                       GetCursorPos(Pt);
                       Shift := ShiftState + [ssLeft];
                       p:=GetClientIconPos(pt);
                       MouseUp(mbLeft, Shift, p.X, p.Y);
                       Click;
                     end;
   WM_RBUTTONDOWN:   begin
                       GetCursorPos(Pt);
                       Shift := ShiftState + [ssRight];
                       p:=GetClientIconPos(pt);
                       MouseDown(mbRight, Shift, p.X, p.Y);
                     end;
   WM_RBUTTONUP:     begin
                       GetCursorPos(Pt);
                       Shift := ShiftState + [ssRight];
                       p:=GetClientIconPos(pt);
                       MouseUp(mbRight, Shift, p.X, p.Y);
                       if FPopupMenu<>nil then
                         FPopupMenu.Popup(pt.X, pt.Y);
                     end;
   WM_LBUTTONDBLCLK: begin
                       DblClick;
                     end;
   WM_MOUSEMOVE:     begin
                       GetCursorPos(Pt);
                       Shift := ShiftState + [ssRight];
                       p:=GetClientIconPos(pt);
                       MouseMove(Shift, p.X, p.Y);
                     end;
 end;

end;
end;
///////////////////////////////////////////////////
procedure TIJTrayIcon.Refresh;
begin
if not(csDesigning in ComponentState) then
 if FVisible then
 begin
   data.hIcon:=FIcon.Handle;
   StrPCopy(data.szTip,FHint);
   Shell_NotifyIcon (NIM_MODIFY,@data);
 end;
end;
//////////////////////////////////////////////////////////////////////////////////////////
Procedure TIJTrayIcon.SetVisible(Value: boolean);
begin
   FVisible:=Value;
   if FVisible then Show else
                    Hide;
end;
////////////////////////////////////////////////////////////////////////////////
Procedure TIJTrayIcon.Show;
begin
 if not(csDesigning in ComponentState) then
 begin
   FVisible:=true;
   Shell_NotifyIcon (NIM_ADD,@data);
   Refresh;
 end;
end;


 
EvilIJ ©   (2006-04-24 12:48) [11]

////////////////////////////////////////////////////////////////////////////////
Procedure TIJTrayIcon.Hide;
begin
 if not(csDesigning in ComponentState) then
 begin
   FVisible:=False;
   Shell_NotifyIcon (NIM_DELETE,@data);
   Refresh;
 end;
end;
////////////////////////////////////////////////////////////////////////////////
Procedure TIJTrayIcon.SetIcon(Value: TIcon);
begin
 FIcon.OnChange := nil;
 FIcon.Assign(Value);
 FIcon.OnChange := IconChanged;
 data.hIcon:=FIcon.Handle;
 Refresh;
end;
////////////////////////////////////////////////////////////////////////////////
Procedure TIJTrayIcon.SetHint(Value: TCaption);
begin
 if Length(Value)>63 then
   Value:=Copy(Value, 1, 63);
 FHint:=Value;
 Refresh;
end;
////////////////////////////////////////////////////////////////////////////////
Procedure TIJTrayIcon.SetShowHint(Value: boolean);
begin
 FShowHint:=Value;
 if FShowHint then
   data.uFlags:=NIF_ICON or NIF_TIP or NIF_MESSAGE else
   data.uFlags:=NIF_ICON or NIF_MESSAGE;
 Refresh;
end;
////////////////////////////////////////////////////////////////////////////////
function TIJTrayIcon.GetClientIconPos(P: TPoint): TPoint;
// Return the cursor position inside the tray icon
const
 IconBorder = 1;
var
 H: HWND;
 IconSize: Integer;
begin
 // Get the icon size
 IconSize := GetSystemMetrics(SM_CYCAPTION) - 3;
 //!!!!!! ПОИСК ОКНА ПОД КУРСОРОМ!!!!!!
 H := WindowFromPoint(P);
 { Convert current cursor X,Y coordinates to tray client coordinates.
   Add borders to tray icon size in the calculations. }
 Windows.ScreenToClient(H, P);
 P.X := (P.X mod ((IconBorder*2)+IconSize)) -1;
 P.Y := (P.Y mod ((IconBorder*2)+IconSize)) -1;
 Result := P;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TIJTrayIcon.Click;
begin
 if Assigned(FOnClick) then
   FOnClick(Self);
end;
////////////////////////////////////////////////////////////////////////////////
procedure TIJTrayIcon.DblClick;
begin
 if Assigned(FOnDblClick) then
   FOnDblClick(Self);
end;
////////////////////////////////////////////////////////////////////////////////
procedure TIJTrayIcon.MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
 if Assigned(FOnMouseDown) then
   FOnMouseDown(Self, Button, Shift, X, Y);
end;
////////////////////////////////////////////////////////////////////////////////
procedure TIJTrayIcon.MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
 if Assigned(FOnMouseUp) then
   FOnMouseUp(Self, Button, Shift, X, Y);
end;
////////////////////////////////////////////////////////////////////////////////
procedure TIJTrayIcon.MouseMove(Shift: TShiftState; X, Y: Integer);
begin
 if Assigned(FOnMouseMove) then
   FOnMouseMove(Self, Shift, X, Y);
end;
////////////////////////////////////////////////////////////////////////////////
Procedure TIJTrayIcon.IconChanged(Sender: TObject);
begin
 Refresh;
end;
////////////////////////////////////////////////////////////////////////////////
end.


 
SuperBug ©   (2006-04-24 18:55) [12]

В общем может я ошибаюсь,но при внимательном изучении хэлпа написано,что события типа  WM_QUERYENDSESSION, WM_ENDSESSION должны возвращать результат,что приложение события отработало и нормально закрывается ,т.е. после вызова обработчиков неплохо было б написать Message.Result:=Integer(True);

что-то типа

if Message.Msg = WM_QUERYENDSESSION then
begin
  if Assigned(FOnQueryEndSession) then
    FOnQueryEndSession(Self);
  Message.Result:=Integer(True);
end;


 
EvilIJ ©   (2006-04-25 08:19) [13]

Спасибо ребята, но увы, код не работает... (((
Может, еще какие предложения?


 
SuperBUG ©   (2006-04-25 17:24) [14]

Признаю свою вину,меру , степень ,глубину.....
Итого результат изысканий на тему (проверено для W2k,WinNT)

1.Для приличия заводим данному компоненту Handle
в секции Private FHandle: THandle;
2.для constructor TIJTrayIcon.Create(AOwner: TComponent);
соответственно меняем строчку

  FHandle:=AllocateHWnd(TrayDefaultHandler);
  ......
  data.Wnd:=FHandle;
  .....

3. в деструкторе destructor TIJTrayIcon.Destroy после
  .....
  Shell_NotifyIcon (NIM_DELETE,@data);
  добавляем
  DeallocateHWND(FHandle)
  ибо ресурсы надо возвращать....

4. в procedure TIJTrayIcon.TrayDefaultHandler (var Message:TMessage)
  создаем вместо множества if...then конструкцию case Msg.Message of
  удаляем нафиг все QueryEndSession, оставляем только UWM_TRAYICON
  т.е. имеем что-то типа

       case Msg.Message of
UWM_TRAYICON:begin
                      end
       else
        with Msg do
          Result:=DefWindowHandler(FHandle,Msg,wParam,lParam);
       end;


Собственно и все.


 
SuperBUG ©   (2006-04-25 17:27) [15]

точнее

      case Msg.Message of
UWM_TRAYICON:begin
                       .....
                       {весь тот код что и раньше}
                       .....
                      end
      else
       with Msg do
         Result:=DefWindowHandler(FHandle,Msg,wParam,lParam);
      end;



 
EvilIJ ©   (2006-04-26 14:06) [16]

Если честно, даже стыдно (на счет того, что я хэндл иконки не глобально объявил)...
Вроде бы все вставил... увы одно НО )
ЧТО ЕСТЬ DefWindowHandler?
Вместо нее я пока вставил
...  else
       with Message do
         Result:= DefWindowProc(FHandle,Msg,wParam,lParam);
Может у меня что с руками или бага в генах ??? ))))


 
EvilIJ ©   (2006-04-26 14:07) [17]

Но винда все равно не гаснет (2000)


 
EvilIJ ©   (2006-04-26 14:08) [18]

Но винда все равно не гаснет (2000)


 
SuperBUG ©   (2006-04-26 15:53) [19]

гмммм......насчет DefWindowProc-она и была,это у меня ошибка пальцев :( слушай,м.б. кинешь мне на мыло тестовый ехешник? у меня просто в таком варианте не только 2к гаснет,но и NT,которая куда более привередливая или могу тебе заслать свой,и ты мне скажешь работает или нет...а то чего-то непонятное...


 
EvilIJ ©   (2006-04-27 10:33) [20]

Получи, распишись)


 
Юрий Зотов ©   (2006-04-27 11:57) [21]

Вот компонент, который ничему не мешает (проверялось под XP). Сравните со своим, найдете причину.


unit YzTrayIcon;

interface

uses
 Windows, ShellAPI, Messages, SysUtils, Classes, Graphics;

type
 TYzTrayIcon = class;
 TChangeReason = (crHint, crIcon, crVisible);
 TChangeEvent = procedure(Sender: TYzTrayIcon; Reason: TChangeReason) of object;

 TYzTrayIcon = class(TComponent)
 private
   FData: TNotifyIconData;
   FIcon: TIcon;
   FVisible: boolean;
   FOnChange: TChangeEvent;
   FOnDblClick: TNotifyEvent;
   function GetHandle: THandle;
   function GetHint: string;
   procedure SetHint(const Value: string);
   procedure SetIcon(const Value: TIcon);
   procedure SetVisible(const Value: boolean);
   procedure IconChange(Sender: TObject);
 protected
   procedure Changed(Reason: TChangeReason);
   procedure Change(Reason: TChangeReason); dynamic;
   procedure DblClick; dynamic;
   procedure WndProc(var Message: TMessage); dynamic;
   procedure Loaded; override;
   property Handle: THandle read GetHandle;
 public
   constructor Create(AOwner: TComponent); override;
   destructor Destroy; override;
 published
   property Hint: string read GetHint write SetHint;
   property Icon: TIcon read FIcon write SetIcon;
   property Visible: boolean read FVisible write SetVisible default True;
   property OnChange: TChangeEvent read FOnChange write FOnChange;
   property OnDblClick: TNotifyEvent read FOnDblClick write FOnDblClick;
 end;

implementation

uses ComObj;

var
 TrayIcon: TYzTrayIcon;

{ TYzTrayIcon }

procedure TYzTrayIcon.Change(Reason: TChangeReason);
begin
 if Assigned(FOnChange) then
   FOnChange(Self, Reason)
end;

procedure TYzTrayIcon.Changed(Reason: TChangeReason);
const
 NIM_MSG: array[boolean] of cardinal = (NIM_DELETE, NIM_ADD);
begin
 if [csDesigning, csLoading] * ComponentState = [] then
   if Reason = crVisible then
     Shell_NotifyIcon(NIM_MSG[FVisible], @FData)
   else
     Shell_NotifyIcon(NIM_MODIFY, @FData);
 Change(Reason)
end;

constructor TYzTrayIcon.Create(AOwner: TComponent);
begin
 if TrayIcon <> nil then
   raise Exception.Create("Component TYzTrayIcon already exists");
 inherited;
 TrayIcon := Self;
 FVisible := True;
 FIcon := TIcon.Create;
 FIcon.OnChange := IconChange;
 if not (csDesigning in ComponentState) then
   with FData do
   begin
     cbSize := SizeOf(FData);
     Wnd := AllocateHWnd(WndProc);
     uID := RegisterWindowMessage("TYzTrayIcon_CallbackMessage");
     uFlags := NIF_MESSAGE;
     uCallbackMessage := uID
   end
end;

procedure TYzTrayIcon.DblClick;
begin
 if Assigned(FOnDblClick) then
   FOnDblClick(Self)
end;

destructor TYzTrayIcon.Destroy;
begin
 Visible := False;
 DeallocateHWnd(Handle);
 FIcon.Free;
 TrayIcon := nil;
 inherited
end;

function TYzTrayIcon.GetHandle: THandle;
begin
 Result := FData.Wnd
end;

function TYzTrayIcon.GetHint: string;
begin
 Result := FData.szTip
end;

procedure TYzTrayIcon.IconChange(Sender: TObject);
begin
 with FData do
 begin
   hIcon := FIcon.Handle;
   if FIcon.Empty then
     uFlags := uFlags and not NIF_ICON
   else
     uFlags := uFlags or NIF_ICON
 end;
 Changed(crIcon)
end;

procedure TYzTrayIcon.Loaded;
begin
 inherited;
 if FVisible then
   Changed(crVisible)
end;

procedure TYzTrayIcon.SetHint(const Value: string);
begin
 if Hint <> Value then
   with FData do
   begin
     if Length(Value) > High(szTip) then
       raise Exception.Create("Too long hint");
     StrPCopy(szTip, Value);
     if Hint = "" then
       uFlags := uFlags and not NIF_MESSAGE
     else
       uFlags := uFlags or NIF_MESSAGE;
     Changed(crHint)
   end
end;

procedure TYzTrayIcon.SetIcon(const Value: TIcon);
begin
 FIcon.Assign(Value)
end;

procedure TYzTrayIcon.SetVisible(const Value: boolean);
begin
 if FVisible <> Value then
 begin
   FVisible := Value;
   Changed(crVisible)
 end
end;

procedure TYzTrayIcon.WndProc(var Message: TMessage);
begin
 with Message do
   if Msg = FData.uCallbackMessage then
   begin
     Result := 0;
     case LParam of
       WM_LBUTTONDBLCLK: DblClick;
       // ... (another messages and handlers)
     end
   end
   else
     Result := DefWindowProc(Handle, Msg, WParam, LParam)
end;

end.


PS
Чтобы не засорять код несущественными деталями, комонент сделан минимальным. Он умеет только показывать/прятать иконку в SysTray и уведомлять о двойном клике по ней. Прочую функциональность добавьте сами.


 
EvilIJ ©   (2006-04-27 12:13) [22]

C Вашим кодом та же фигня, походу, всетаки дело не в компоненте...
EvilIJ ©   (24.04.06 08:43) [4]
Надо ковырять саму программу...
Если интересно, ту же прогу я написал на VC6.0 и такой проблемы НЕБЫЛО.
эх...


 
EvilIJ ©   (2006-04-27 12:23) [23]

)))))) И все же решение нашлось, хотя и "не правильное" ))))
Сообщения WM_END.. и Q... я отловил в самой программе(не в компоненте) и вместо CLOSE (так было раньше) вставил HALT.))))) ВСЕ ПУЧКОМ )))
Кстати, я забыл сказать, что главное окно моей программы прячится "в трэй",
возможно, виндуза просто не могла до него долесть, ведь в дельфях "главная" форма все равно сидит под Application, а у него есть свой хэндл. А в WndProc Application-а я не лазил, кто знает, что там )
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ \\\\\\\\\
Все равно всем спасибо, это мой первый форум, было интересно )
С уважением, IJ...


 
Nostradamus   (2006-04-27 19:21) [24]

У тебя в OnClose скорее всего написано что-то типа

CanClose := False;
Hide;


Чтобы сворачивать пргу в трей.

Если убрать CanClose := False;, то винда будет выключаться



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2006.08.20;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.55 MB
Время: 0.042 c
15-1153604106
Германн
2006-07-23 01:35
2006.08.20
Скушно!


1-1152141034
xsid
2006-07-06 03:10
2006.08.20
Выделение картинки


2-1154156127
Fosgen
2006-07-29 10:55
2006.08.20
Создание массива констант из указателей method pointers


5-1138109150
Юрий Ж.
2006-01-24 16:25
2006.08.20
[s]RxLib for Delphi2006


2-1154453897
bobbi
2006-08-01 21:38
2006.08.20
посчитать количество символов в stringlist





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский