-
перехватываю комбинацию в onkeydown контрола мне необходимо чтобы работала моя вставка в clipboard, а не системная
if (ssCtrl in Shift) and (Key = Ord('C')) then
begin
Clipboard.Clear;
MYPasteToClipBoard;
end; такой код не фурычит в OnKeyUP - работает - но нужно долго держать клавиши и отпускать в определенной последовательности, сначала 'С' затем Ctrl. С помощью таймера можно заставить работать но это блин смешно и криворуко. Существует ли корректный код для запрета CTRL+C (именно чтобы система не лезла в буфер)?
-
> allrussia (21.05.10 05:07)
> перехватываю комбинацию в onkeydown контрола
WM_COPY ?
-- Regards, LVT.
-
брось на форму edit положми в него текст потом Edit.Selettall. edit.copytoclipbord попробуй мож пойдет
-
тю ты чота я не о том :) если тебе нужно чтоб твои компоненты не реагировали на комбинацию клавишь, то key:=#0 в конце onkeydown ну а если не в твоем окне то только хук на систему вешать.
-
> [0] allrussia (21.05.10 05:07) > перехватываю комбинацию в onkeydown контрола > мне необходимо чтобы работала моя вставка в clipboard, а не системная
IMHO, достаточно перехватить две ф-ии: SetClipboardData, EmptyClipboard Во всяком случае, мне в похожей задачке этого хватило.
-
> Leonid Troyanovsky
> WM_COPY ?
Вы вопрос поняли? Мне нужно чтобы по нажатию Ctrl+C на любом контроле вистема не копировала содержимое в буфер обмена. (Это примерно то же самое что перехват Ctrl+Alt+Del, просто здесь библиотека не участвует) Как скопировать содержимое я знаю.
MKC
если тебе нужно чтоб твои компоненты не реагировали на комбинацию клавишь, то key:=#0 в конце onkeydown
вы тоже особо не поняли видимо: #0 - Это тип Char, а не Word, во вторых - это все равно не поможет (сама система ОС Windows перехватывает CTRL+С, не делфи)
Riply
> IMHO, достаточно перехватить две ф-ии: SetClipboardData, > EmptyClipboard > Во всяком случае, мне в похожей задачке этого хватило.
Прекрасно - подскажите как или привдите рабочий пример
достаточно будет нажать CTRL+C на TEdit или TMemo и чтобы буфер обмена оказался пустым или с предыдущими данными
-
> [5] allrussia (21.05.10 16:25) > Riply > Прекрасно - подскажите как или привдите рабочий пример
"Подсказать как" что ? Как перехватывать API ? Если да, то это хорошо расписано у Рихтера и даже с примерами :), а если нет, то что именно подсказать ?
> достаточно будет нажать CTRL+C на TEdit или TMemo > и чтобы буфер обмена оказался пустым или с предыдущими данными
Эмн... а к чему эта фраза, да еще и выделенная ? Разве данные операции работают не через SetClipboardData, EmptyClipboard ?
-
> onkeydown > OnKeyUP
ну - попробуй onkeypress до кучи if( key = ^c )then begin ... key: = #0; end;
-
> Эмн... а к чему эта фраза, да еще и выделенная ? > Разве данные операции работают не через SetClipboardData, > EmptyClipboard ? спасибо, вот что удалось надыбать function NewMemoProc(wnd:HWND; uMsg:UINT; wParam:WPARAM; lParam:LPARAM):integer; stdcall;
begin
if (uMsg = WM_CUT) or (uMsg = WM_COPY) then uMsg := 0;
result:=CallWindowProc(Pointer(GetWindowLong(wnd,GWL_USERDATA)),wnd,uMsg,wParam, lParam)
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
SetWindowLong(Memo1.Handle,GWL_USERDATA,SetWindowLong(Memo1.Handle, GWL_WNDPROC, LPARAM(@NewMemoProc)))
end;
собственно вопрос: 1. как сделать чтобы применялось для всех edit-, memo-, text-контролов? 2. корректен ли этот код и можно ли избежать такой громоздкости? for i:= 0 to ComponentCount -1 do SetWindowLong(component[i].handle,GWL_USERDATA,SetWindowLong(component[i].handle , GWL_WNDPROC, LPARAM(@NewMemoProc)))
-
han_malign
спасибо вариант хороший, но 1 проблема: когда отпускаешь первым Ctrl начинают вводиться буквы 'C'
2 придется русками везде прописывать на всех контролах и ctrl +C и Ctrl+X (с отловом позиции курсора, а ведь есть еще ctrl+Ins и пр...) + проблема 1
-
тебе надо перехватывать WM_COPY.
В древнем Китае желающим странного отрубали голову. Весьма эффективный метод, надо признать.
-
> Игорь Шевченко © (21.05.10 19:49) [10] > > тебе надо перехватывать WM_COPY.
не тебе, а вам. спасибо за экскурс в историю
а это что (21.05.10 17:11) [8],не перехват WM_COPY? Появились другие вопросы в [8] и [9].
-
allrussia (21.05.10 19:54) [11]
> не тебе, а вам
а нам это нафиг не сдалось
> корректен ли этот код и можно ли избежать такой громоздкости?
Для решения тупой задачи вполне годится такой тупой код.
Но гораздо проще надписать компоненты и в них заменять оконную процедуру на нужную (как это неоднократно демонстрируется в stdctrls.pas)
-
Игорь Шевченко > Для решения тупой задачи вполне годится такой тупой код.
поясните, почему тупой... вы не пользуетесь CTRL+C,CTRL+V? :))
в целом задача такова: корректное копирование русского текста в буфер при нажатии комбинации клавиш CTR+C, Ins в Vista, 7, 2008 из контролов Delphi, не поддерживающих юникод
-
-
Игорь Шевченко
> тоже способ предлагают, без перехвата.
спасибо, но у меня оба эти линка постоянно открыты :) и не только эти, а еше как минимум 3 способа RUSClip - например ничего не дает и не обрабатывается вручную (например через попап меню) скопировать корректно текст не проблема
основная проблема заключается в перехвате CTRL+C
-
allrussia (21.05.10 20:32) [15] Проблема заключается в том, чтобы установить корректную кодовую страницу в Clipboard. Перехватывать кучу клавиатурных комбинаций - это не всегда и не совсем удобно. Можно конечно пробегаться по формам и переустанавливать оконные процедуры, но типов контролов много (кстати, сами формы (RTFS: Dialogs.TMessageForm) тоже могут быть скопированы по Ctrl+C, не только Edit-ы и их производные, и результаты копирования подчиняются тем же правилам кодовой страницы) и для каждого переопределять оконную процедуру, мягко говоря, не очень разумно. Если перехватывать, то лучше надписывать компоненты (можно по способу Geo http://www.interface.ru/home.asp?artId=16753) и в их обработчике WM_COPY, WM_CUT устанавливать нужную кодовую страницу.
-
> allrussia (21.05.10 16:25) [5]
> Вы вопрос поняли? Мне нужно чтобы по нажатию Ctrl+C на любом > контроле вистема не копировала содержимое в буфер обмена. > (Это примерно то же самое что перехват Ctrl+Alt+Del, просто
Вопрос мы поняли. Не надо - не копируй. Хотя, про любой - это, дейс-но, новость.
Перехватом же Ctrl+Alt+Del мы и не заморачиваемся.
-- Regards, LVT.
-
Игорь Шевченко > Проблема заключается в том, чтобы установить корректную > кодовую страницу в Clipboard.
Это я знаю и добиваюсь. Перехватывать кучу клавиатурных комбинаций - это не всегда и не совсем удобно.
Неудобно. Но рука тянется к клавишам, а не ПКМ. Хочется нормальный русский текст по CTRL+C. > Если перехватывать, то лучше надписывать компоненты (можно > по способу Geo http://www.interface.ru/home.asp?artId=16753) >
как "надписывание" поможет перехватить CTRL+С? вы можете показать хоть 1 рабочий пример, где происходит корректное копирование/вставка в/из Memo в/из буфер обмена с помощью системных комбинаций клавиш Ctrl,Shift,C,Ins? вот так?
procedure TForm1.WndProc (var message: TMessage);
begin
if (message.Msg = WM_COPY) or (message.Msg = WM_CUT) then
else
inherited
end; тишина
-
allrussia (21.05.10 22:51) [18] > вы можете показать хоть 1 рабочий пример, где происходит > корректное копирование/вставка в/из Memo в/из буфер обмена > с помощью системных комбинаций клавиш Ctrl,Shift,C,Ins?
Могу показать 1 пример: TForm1 = class(TForm)
Edit1: TEdit;
Memo1: TMemo;
private
FOldMemoWndProc: TWndMethod;
FOldEditWndProc: TWndMethod;
procedure MemoWndProc (var Message: TMessage);
procedure EditWndProc (var Message: TMessage);
end;
var
Form1: TForm1;
implementation
procedure TForm1.FormCreate(Sender: TObject);
begin
FOldMemoWndProc := Memo1.WindowProc;
Memo1.WindowProc := MemoWndProc;
FOldEditWndProc := Edit1.WindowProc;
Edit1.WindowProc := EditWndProc;
Memo1.Lines.Text := 'Это русский текст';
end;
procedure TForm1.MemoWndProc(var Message: TMessage);
var
LKL: array [0..1023] of char;
begin
if Message.Msg = WM_COPY then
begin
GetKeyboardLayoutName(LKL);
LoadKeyboardLayout('00000419',KLF_ACTIVATE);
end;
FOldMemoWndProc(Message);
if Message.Msg = WM_COPY then
LoadKeyboardLayout(LKL,KLF_ACTIVATE);
end;
procedure TForm1.EditWndProc(var Message: TMessage);
var
LKL: array [0..1023] of char;
begin
if Message.Msg = WM_COPY then
begin
GetKeyboardLayoutName(LKL);
LoadKeyboardLayout('00000419',KLF_ACTIVATE);
end;
FOldEditWndProc(Message);
if Message.Msg = WM_COPY then
LoadKeyboardLayout(LKL,KLF_ACTIVATE);
end; В случае надписанного же компонента в его обработчике сообщений WM_COPY/WM_CUT будет такая же операция мамбл-ванго, как в примере, вызов inherited для обработки сообщения родным контролом и восстановление раскладки.
-
копирование произоводится корректно, как при Ctrl+C, Ctrl+Ins там и при вызове из локального меню
-
Игорь Шевченко © (21.05.10 23:16) [20]
копирование произоводится корректно, как при Ctrl+C, Ctrl+Ins там и при вызове из локального меню спасибо за пример - он безусловно пока самый рабочий. В принципе у меня он был немного в другом виде, но метод запомнить раскладку, сменить на русский и затем обратно я уже использовал. Я как раз ищу рабочий пример без смены раскладки. Во-вторых, вопрос к вам как к программисту: как поведет себя код при отсутствии русской раскладки? Я пробовал удалять раскладки и код работает, но все же, какие могут быть курьезы? И в-третьих, как же быть со вставкой? Основная проблема здесь: Открываем блокнот Windows. переключаем раскладку на русский. пишем текст. переключаем обратно на англ. копируем в буфер. вставляем в мемо в нашу программу (форма и мемо). результат: "?" и абракадабра... Здесь уже не моможет включение русской раскладки перед вставкой, т.к. русский текст был скопирован с некорректной кодовой страницей в Clipboard.
-
да, и еще вопрос, как это размножить на 100 мемо программно procedure TForm1.FormCreate(Sender: TObject);
begin
FOldMemoWndProc := Memo1.WindowProc;
Memo1.WindowProc := MemoWndProc;
FOldEditWndProc := Edit1.WindowProc;
Edit1.WindowProc := EditWndProc;
Memo1.Lines.Text := 'Это русский текст';
end;
procedure TForm1.MemoWndProc(var Message: TMessage);
var
LKL: array [0..1023] of char;
begin
if Message.Msg = WM_COPY then
begin
GetKeyboardLayoutName(LKL);
LoadKeyboardLayout('00000419',KLF_ACTIVATE);
end;
FOldMemoWndProc(Message);
if Message.Msg = WM_COPY then
LoadKeyboardLayout(LKL,KLF_ACTIVATE);
end;
-
allrussia (22.05.10 00:08) [21] Мне, если честно, лень искать материалы по работе с Clipboard. Разумеется, переключение языка раскладки - это грубый (и не всегда полезный) метод. То, что при этом Clipboard устанавливает нужный формат - это побочный эффект от переключения, я уверен, что этого же эффекта можно добиться прямым путем. вот тут http://www.codeguru.com/cpp/w-p/clipboard/article.php/c3009есть неплохая программка, которая позволяет крутить данные в Clipboard под разным углом. Вот тут ( http://msdn.microsoft.com/en-us/library/ms649013(VS.85).aspx ) есть описание, почему действует переключение клавиатуры: "The data is a handle to the locale identifier associated with text in the clipboard. When you close the clipboard, if it contains CF_TEXT data but no CF_LOCALE data, the system automatically sets the CF_LOCALE format to the current input language. You can use the CF_LOCALE format to associate a different locale with the clipboard text. An application that pastes text from the clipboard can retrieve this format to determine which character set was used to generate the text." Твори, выдумывай, пробуй.
-
allrussia (22.05.10 00:25) [22]
> да, и еще вопрос, как это размножить на 100 мемо программно
Написать наследник от TMemo и использовать наследник. Заменять можно и в runtime
-
> Заменять можно и в runtime
<offtop> Эх, если бы были механизмы/утилиты сделать подобное в designtime. </offtop>
-
спасибо, но со вставкой все равно непонятно в этом случае как быть
Открываем блокнот Windows. переключаем раскладку на русский. пишем текст. переключаем обратно на англ. копируем в буфер. вставляем в мемо в нашу программу (форма и мемо). результат: "?" и абракадабра...
здеть уже SetClipBoardData(CF_Locale,0419) не помогает..... ведь копирование было средствами ОС из чужой программы
-
вот тут http://www.codeguru.com/cpp/w-p/clipboard/article.php/c3009 есть неплохая программка, которая позволяет крутить данные в Clipboard под разным углом.да а смысл? я сам могу "крутить" данные с помощью кнопок и мыши (вы сами мне давали функцию BufferToClipBoard)... Мне-то нужно перехватывать системную вставку-копирование.. тем более прога под последними ОС не фурычит...
-
Вот как я это делел, без завязки на русский: procedure SendKeyboardLayout(Wnd, Msg:int; lParam:int=0; wParam:int=0);
var a:HKL; s:string;
begin
SetLength(s,8);
Win32Check(GetKeyboardLayoutName(ptr(s)));
if s='00000409' then
begin
a:=ActivateKeyboardLayout(
LoadKeyBoardLayout(ptr(intToHex(GetUserDefaultLangID,8)),0),0);
if a=0 then RaiseLastOSError;
SendMessage(Wnd, Msg, lParam, wParam);
if ActivateKeyboardLayout(a,0)=0 then RaiseLastOSError;
end else
SendMessage(Wnd, Msg, lParam, wParam);
end;
procedure TForm1.Copy1Click(Sender: TObject);
begin
SendKeyboardLayout(GetFocus, WM_COPY);
end;
procedure TForm1.Cut1Click(Sender: TObject);
begin
SendKeyboardLayout(GetFocus, WM_CUT);
end;
procedure TForm1.Paste1Click(Sender: TObject);
begin
SendMessage(GetFocus, WM_PASTE, 0, 0);
end; Это код для пунктов меню. Если кодировка английская, он устанавливает кодировку для языка пользователя. Перехват оконной процедуры у тебя нормальный, только не понятно, откуда ты нашел Handle у TComponent - он только у TWinControl. Игорь Шевченко © (21.05.10 19:58) [12] Но гораздо проще надписать компоненты и в них заменять оконную процедуру на нужную (как это неоднократно демонстрируется в stdctrls.pas)Не-не-не. Только лишняя морока. А этот метод еще можно продолжыть, отлавливая создание дочерних контролов. Игорь Шевченко © (22.05.10 0:28) [23]Спасибо, это интересно.
-
GrayFace © (22.05.10 22:20) [28]
> Не-не-не. Только лишняя морока. А этот метод еще можно продолжыть, > отлавливая создание дочерних контролов.
Сказки не рассказывай, ладно ?
> procedure SendKeyboardLayout(Wnd, Msg:int; lParam:int=0; > wParam:int=0);
Срочно читать Фаулера. Наизусть.
Почему помогает смена языка клавиатуры - потому что ясным английским языком написано, что если при закрытии Clipboard locale не установлен, то он становится равным текущему языку ввода. Умные люди советуют передавать CF_UNICODETEXT и, соответственно, строку в Unicode (UCS-2), которая при вставке в Ansi-контрол должна быть преобразована в соотвествии с locale потока, а не языка ввода. А он по умолчанию равен языку локализации системы :)
-
GrayFace > Это код для пунктов меню.
тема совсем не о пунктах меню. с пунктами меню проблем нет, причем приведены более удобные методы BufferToClipBoardкстати, вот это
procedure TForm1.Paste1Click(Sender: TObject);
begin
SendMessage(GetFocus, WM_PASTE, 0, 0);
end; у вас даже не сработает, если Открываем блокнот Windows. переключаем раскладку на русский. пишем текст. переключаем обратно на англ. копируем в буфер. вставляем в мемо в нашу программу (форма и мемо). результат: "?" и абракадабра...будет та же абракадабра... :)) увы, ваш вариант не принимается :( просто с помощью меню никто не копирует это долго и нудно основная задача заменить операции стандартных комбинации клавиш на свои
-
> allrussia
не совсем вкурсе вопроса насчет раскладок и кодовых страниц клипбоарда, сам не сталкивался с этой проблемой в плане разработки, только слышал.
но что если просто отслеживать буфер обмена (благо есть такие функции) и, в случае появления кривого, текста вручную подменять его, к примеру, на юникодовский вариант?
-
-
Я сильно извиняюсь, а что, пользователей нельзя попросить вручную переключиться на русский язык перед копированием ? Мои пользователи и я научились.
К тому же в последних версиях Delphi этой проблемы нет, так как юникод.
Я к чему - конечно чистое искусство, это хорошо и красиво, но стоит ли овчинка выделки ? Если бы подобный механизм был бы действительно необходим и востребован, MS бы давно придумал нужный API для изменения поведения Clipboard в желаемую сторону.
-
> Я к чему - конечно чистое искусство, это хорошо и красиво, > но стоит ли овчинка выделки ?
+1
-
> Я сильно извиняюсь, а что, пользователей нельзя попросить > вручную переключиться на русский язык перед копированием > ? Мои пользователи и я научились. >
Можно, просто у меня другой подход к созданию собственных программ. Просто я - админ, и мое кредо: для пользователей должно быть все прозрачно. Для меня - "кривые руки программиста" - это не "кривой" (пусть даже дебильный) для вас, программистов с большой буквы, код, а "кривая" работа программы, в данном случае, непродуманность в отношении буфера обмена Windows; в общих случаях, ка правило, это неюзабельный интерфейс, отсутствие горячих клавиш, многозадачности и многопоточности и пр. Меня красота кода не волнует. Поэтому и считаю, что хороший и талантливый программист, как правило, хреновый дизайнер и наоборот. Я из последних.
-
> Просто я - админ, и мое кредо: для пользователей должно > быть все прозрачно.
Переходи на Delphi 2009 и выше. На неюникодных версиях красивого решения, боюсь, нет.
-
> непродуманность в отношении буфера обмена Windows
> хороший и талантливый программист
на самом деле все в буфере продумано,а вы видимо не такой талантливый, раз в этом сомневаетесь для начала стоит изучить первоисточники,типа msdn а не "самоучитель дельфи глава 7 TClipboard"
так вот ,о чем это я 1)чтобы "перехватить" Ctrl+с и тд нужно просто перерегистрировать данный хоткей в своей проге (невероятно ,правда?) 2)буфер может хранить текст сразу в 3х кодировках дос,анси и уникод. Но! все почемуто используют тока одну (вот и зависимость от текущей клавы) что из этого следует... 1)ловим нажатие хоткея в очереди главного окна 2)смотрим какая кодировка в буфере и конвертируем в нужную или винда сделает это сама если в буфере установить нужный локаль(иначе возьмет текущую раскладку клавы) 3)когда копируем из себя то,либо забиваем в буфер сразу в 3х кодировках, либо одну и в буфере установить нужный локаль(иначе возьмет текущую раскладку клавы) 4)и естествено мы забиваем на всякие TClipboard ,а используем АПИ вот и вся теория...
ps есть ищо варианты
-
> нужно просто перерегистрировать данный хоткей в своей проге
правда придется еще чучуть доработать штоб работало во всей системе после етого ;)
-
Окончательный рабочий вариант
var cl: string;
...
procedure ClipboardCopy(const Text: String);
var
Len, wLen: Integer;
hClip: THandle;
pwStr: PWideChar;
begin
with Clipboard do
begin
Open;
try
if (Win32Platform = VER_PLATFORM_WIN32_NT) then
begin
Len := Length(Text) + 1;
wLen := Len shl 1;
hClip := GlobalAlloc(GMEM_MOVEABLE, wLen);
try
pwStr := PWideChar(GlobalLock(hClip));
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, PChar(Text), Len, pwStr, wLen);
GlobalUnlock(hClip);
SetAsHandle(CF_UNICODETEXT, hClip);
except
GlobalFree(hClip);
raise;
end;
end else
SetTextBuf(PChar(Text));
finally
Close;
end;
end;
end;
procedure ClipboardPaste(var Text: String);
var
Len, wLen: Integer;
hClip: THandle;
pwStr: PWideChar;
begin
Text := '';
with Clipboard do
try
Open;
if HasFormat(CF_TEXT) or HasFormat(CF_UNICODETEXT) then
begin
if (Win32Platform = VER_PLATFORM_WIN32_NT) then
begin
hClip := GetAsHandle(CF_UNICODETEXT);
wlen := GlobalSize(hClip);
pwStr := GlobalLock(hClip);
try
Len := (wLen div 2) - 1;
SetLength(Text, Len);
WideCharToMultiByte(CP_ACP, 0, pwStr, wlen, PChar(Text), Len, nil, nil);
finally
GlobalUnlock(hClip);
end;
end else
begin
hClip := GetAsHandle(CF_TEXT);
Len := GlobalSize(hClip);
SetLength(Text, Len);
SetLength(Text, GetTextBuf(PChar(Text), Len));
end;
end;
finally
Close;
end;
end;
function NewMemoProc(wnd:HWND; uMsg:UINT;
wParam:WPARAM; lParam:LPARAM):integer; stdcall;
begin
case uMsg of
WM_COPY:
begin
uMsg:=0;
ClipboardCopy(cl);
end;
WM_CUT:
begin
SendMessage(wnd,EM_REPLACESEL,1,cardinal(pchar('')));
uMsg:=0;
ClipboardCopy(cl);
end;
WM_PASTE:
begin
uMsg:=0;
ClipboardPaste(cl);
end;
end;
Result:= CallWindowProc(Pointer(GetWindowLong(wnd,GWL_USERDATA)),
wnd,uMsg,wParam,lParam);
end;
form1.create
procedure CreateOwnClipboard;
var i: integer;
h: hwnd;
c: TComboBoxInfo;
begin
with form1 do
for i :=0 to componentCount - 1 do
begin
if Components[i] is TEdit then
begin
h:= TEdit(Components[i]).Handle;
SetWindowLong(h,GWL_USERDATA,SetWindowLong(h, GWL_WNDPROC, LPARAM(@NewMemoProc)))
end;
if Components[i] is TMemo then
begin
h:= TMemo(Components[i]).Handle;
SetWindowLong(h,GWL_USERDATA,SetWindowLong(h, GWL_WNDPROC, LPARAM(@NewMemoProc)))
end;
if Components[i] is TComboBox then
begin
c.cbSize:= SizeOf(TCOMBOBOXINFO);
GetComboBoxInfo(TComboBox(Components[i]).Handle,c);
h:= c.hwndItem;
SetWindowLong(h,GWL_USERDATA,SetWindowLong(h, GWL_WNDPROC, LPARAM(@NewMemoProc)))
end;
end;
end;
MemoKeyDown
begin
with TFlat(Sender) do
begin
if not ReadOnly then
if ((Key = ord('V')) and (ssCtrl in Shift)) or
((Key = VK_INSERT) and (ssShift in Shift)) then
begin
SelText:=cl;
end;
if ((Key = ord('C')) and (ssCtrl in Shift)) or
((Key = VK_INSERT) and (ssCtrl in Shift)) or
((Key = ord('X')) and (ssCtrl in Shift)) or
((Key = VK_DELETE) and (ssShift in Shift)) then
cl:= SelText;
end;
end;
так же по аналогии с EditOnKeyDown и ComboboxOnKeyDown
-
> allrussia (23.05.10 00:48) [30] Мой код зато не завязан на русский язык. Твой финальный, вроде, тоже.
-
Игорь Шевченко © (23.05.10 0:39) [29] Сказки не рассказывай, ладно ? И так не рассказываю.
Игорь Шевченко © (23.05.10 0:39) [29] Срочно читать Фаулера. Наизусть. Название функции плохое? А есть ссылка на Фаулера? Мартин Фаулер, Рефакторинг. Улучшение существующего кода?
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
-
Удалено модератором
|