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

Вниз

О провилах хорошего тона в программировании.   Найти похожие ветки 

 
Юрий Зотов ©   (2004-04-09 17:03) [200]

> Style ©   (09.04.04 16:45) [192]

Посмотрел Windows.pas - действительно ругнется. Но совсем не о том речь.

> pasha_golub ©   (09.04.04 16:50) [194]
> я ж проверяю чтобы не была андефайнд

Это тебе так кажется, Паш, а на самом деле ни фига ты не проверяешь. Дело в том, что компилятор совершенно справедливо предполагает, что в результате вызова inherited DrawCell значение FWordBreak могло измениться с False на True - и тогда ты попал, OldVal будет неопределена. О чем он тебе и говорит.

> pasha_golub ©   (09.04.04 16:49) [193]
> нужно сделать иное

Эт-точно. Нужно ввести свойство WordBrake и метод Set для него, а в этом методе синхронно менять DefaultDrawing, как надо. А код, который ты привел, надо сделать даже еще проще:
if WordBreak then DrawText(...) else inherited;
И все.


 
Юрий Зотов ©   (2004-04-09 17:03) [200]

> Style ©   (09.04.04 16:45) [192]

Посмотрел Windows.pas - действительно ругнется. Но совсем не о том речь.

> pasha_golub ©   (09.04.04 16:50) [194]
> я ж проверяю чтобы не была андефайнд

Это тебе так кажется, Паш, а на самом деле ни фига ты не проверяешь. Дело в том, что компилятор совершенно справедливо предполагает, что в результате вызова inherited DrawCell значение FWordBreak могло измениться с False на True - и тогда ты попал, OldVal будет неопределена. О чем он тебе и говорит.

> pasha_golub ©   (09.04.04 16:49) [193]
> нужно сделать иное

Эт-точно. Нужно ввести свойство WordBrake и метод Set для него, а в этом методе синхронно менять DefaultDrawing, как надо. А код, который ты привел, надо сделать даже еще проще:
if WordBreak then DrawText(...) else inherited;
И все.


 
Матлабист   (2004-04-09 17:05) [201]

Лично я пишу без хинтов и варнингов. Условный рефлекс --- как только появляется варнинг --- компиляция прерывается. Мне проще написать строку вроде


 OldVal := False; // Kill warning


Даже если все нормально, Warning часто говорит о том, что код все-же лучше как-то переработать (он неудобочитаем).


> откула компилятор может знать, что inherited DrawCell не
> изменит значения FWordBreak?

Или другой поток...


 
Матлабист   (2004-04-09 17:05) [201]

Лично я пишу без хинтов и варнингов. Условный рефлекс --- как только появляется варнинг --- компиляция прерывается. Мне проще написать строку вроде


 OldVal := False; // Kill warning


Даже если все нормально, Warning часто говорит о том, что код все-же лучше как-то переработать (он неудобочитаем).


> откула компилятор может знать, что inherited DrawCell не
> изменит значения FWordBreak?

Или другой поток...


 
pasha_golub ©   (2004-04-09 17:05) [202]

nikkie ©   (09.04.04 16:58) [198]
Компилятор не знает, а я знаю :-)

Это я к тому, что тут кричали:" мол ворнинги, хинты, надо шобы не было".

А я к тому, шо голову не заменить. Этот ворнинг я просто подавил:

{$WARNING OFF}


 
pasha_golub ©   (2004-04-09 17:05) [202]

nikkie ©   (09.04.04 16:58) [198]
Компилятор не знает, а я знаю :-)

Это я к тому, что тут кричали:" мол ворнинги, хинты, надо шобы не было".

А я к тому, шо голову не заменить. Этот ворнинг я просто подавил:

{$WARNING OFF}


 
Игорь Шевченко ©   (2004-04-09 17:09) [203]


> Компилятор не знает, а я знаю :-)

> Это я к тому, что тут кричали:" мол ворнинги, хинты, надо шобы > не было".
> А я к тому, шо голову не заменить. Этот ворнинг я просто
> подавил:
>
> {$WARNING OFF}


Мне подписаться ? ;)


 
Игорь Шевченко ©   (2004-04-09 17:09) [203]


> Компилятор не знает, а я знаю :-)

> Это я к тому, что тут кричали:" мол ворнинги, хинты, надо шобы > не было".
> А я к тому, шо голову не заменить. Этот ворнинг я просто
> подавил:
>
> {$WARNING OFF}


Мне подписаться ? ;)


 
nikkie ©   (2004-04-09 17:11) [204]

if FWordBreak then begin
 ...
 OldVal := DefaultDrawing;
 inherited DrawCell(...);
 DefaultDrawing := OldVal;
end else
 inherited DrawCell(...);


имхо, так и варнинг исчезнет и будет легче читаться

>мол ворнинги, хинты, надо шобы не было
согласен, хорошо бы.


 
nikkie ©   (2004-04-09 17:11) [204]

if FWordBreak then begin
 ...
 OldVal := DefaultDrawing;
 inherited DrawCell(...);
 DefaultDrawing := OldVal;
end else
 inherited DrawCell(...);


имхо, так и варнинг исчезнет и будет легче читаться

>мол ворнинги, хинты, надо шобы не было
согласен, хорошо бы.


 
Юрий Зотов ©   (2004-04-09 17:13) [205]

> pasha_golub ©   (09.04.04 17:05) [202]

Варнинги, конечно, можно и давить, дело хозяйское. Только потом не удивляйся, откуда вдруг ошибки полезли и почему их так трудно искать.

Паш, просто поверь - ТАК не пишут, это любительщина. Когда-нибудь ты и сам придешь к тому же, а сейчас - просто поверь.


 
Юрий Зотов ©   (2004-04-09 17:13) [205]

> pasha_golub ©   (09.04.04 17:05) [202]

Варнинги, конечно, можно и давить, дело хозяйское. Только потом не удивляйся, откуда вдруг ошибки полезли и почему их так трудно искать.

Паш, просто поверь - ТАК не пишут, это любительщина. Когда-нибудь ты и сам придешь к тому же, а сейчас - просто поверь.


 
pasha_golub ©   (2004-04-09 17:59) [206]

nikkie ©   (09.04.04 17:11) [204]
Во, точно. Спасибо. Око замыленное, не увидел.

Юрий Зотов ©   (09.04.04 17:13) [205]
В этом конкретном месте, не удивлюсь ибо не будет!

Игорь Шевченко ©   (09.04.04 17:09) [203]
Не трать патроны. ;-)

Юрий Зотов ©   (09.04.04 17:03) [200]
Не в свойстве WordBreak тут соль, дело в другом.


 
pasha_golub ©   (2004-04-09 17:59) [206]

nikkie ©   (09.04.04 17:11) [204]
Во, точно. Спасибо. Око замыленное, не увидел.

Юрий Зотов ©   (09.04.04 17:13) [205]
В этом конкретном месте, не удивлюсь ибо не будет!

Игорь Шевченко ©   (09.04.04 17:09) [203]
Не трать патроны. ;-)

Юрий Зотов ©   (09.04.04 17:03) [200]
Не в свойстве WordBreak тут соль, дело в другом.


 
Style ©   (2004-04-09 18:00) [207]

2 Юрий Зотов ©   (09.04.04 17:13) [205]
т.е. OldVal := False; // Kill warning
такого рода "заглушки" не стоит использовать???


 
Style ©   (2004-04-09 18:00) [207]

2 Юрий Зотов ©   (09.04.04 17:13) [205]
т.е. OldVal := False; // Kill warning
такого рода "заглушки" не стоит использовать???


 
pasha_golub ©   (2004-04-09 18:04) [208]

Style ©   (09.04.04 18:00) [207]
Дейтсвительно, эта строка ворнинг уберет. Однако не считаю, что от отсутствия оной стиль можно счатитать.

Еще раз nikkie спасибо, блин, а все так просто. Эх мозги, мозги. :-)


 
pasha_golub ©   (2004-04-09 18:04) [208]

Style ©   (09.04.04 18:00) [207]
Дейтсвительно, эта строка ворнинг уберет. Однако не считаю, что от отсутствия оной стиль можно счатитать.

Еще раз nikkie спасибо, блин, а все так просто. Эх мозги, мозги. :-)


 
Style ©   (2004-04-09 18:07) [209]


> Дейтсвительно, эта строка ворнинг уберет. Однако не считаю,
> что от отсутствия оной стиль можно счатитать.


Но наверняка есть такие случаи когда "пустое!" определение переменной нужно? Особенно когда много ифов.. и эта переменная реально может быть не определена.


 
Style ©   (2004-04-09 18:07) [209]


> Дейтсвительно, эта строка ворнинг уберет. Однако не считаю,
> что от отсутствия оной стиль можно счатитать.


Но наверняка есть такие случаи когда "пустое!" определение переменной нужно? Особенно когда много ифов.. и эта переменная реально может быть не определена.


 
Desdechado ©   (2004-04-09 18:16) [210]

А я, например, люблю использовать TList для хранения Integer"ов, а ведь у него Pointer"ы. И вот на каждом таком преобразовании Д7 плюется.
Было и такое поведение. Объявил тип. Переменная и свойство класса этого типа. Присваивание одного другому вызывает варнинг unsafe type conversion TNagr to TNagr.


 
Desdechado ©   (2004-04-09 18:16) [210]

А я, например, люблю использовать TList для хранения Integer"ов, а ведь у него Pointer"ы. И вот на каждом таком преобразовании Д7 плюется.
Было и такое поведение. Объявил тип. Переменная и свойство класса этого типа. Присваивание одного другому вызывает варнинг unsafe type conversion TNagr to TNagr.


 
Style ©   (2004-04-09 18:21) [211]


> Desdechado ©


А не судьба
unsafe type conversion
отключить??


 
Style ©   (2004-04-09 18:21) [211]


> Desdechado ©


А не судьба
unsafe type conversion
отключить??


 
Desdechado ©   (2004-04-09 18:26) [212]

мне нужно НЕ ПРЯТАТЬ варнинг, а разобраться в нем. Ибо иногда небезопасные преобразования случайно влепишь, ине найдешь потом...


 
Desdechado ©   (2004-04-09 18:26) [212]

мне нужно НЕ ПРЯТАТЬ варнинг, а разобраться в нем. Ибо иногда небезопасные преобразования случайно влепишь, ине найдешь потом...


 
Юрий Зотов ©   (2004-04-09 18:39) [213]

> pasha_golub ©   (09.04.04 18:04) [208]

Паш, это, насколько я понял, компонент?

Тогда свойство нужно. Обязательно нужно - вот именно для того, о чем я писал. Иначе - тоже любительщина, так компоненты не пишут.

Не веришь - спроси у Майка с Женей. Они подтвердят.
:о)


 
Юрий Зотов ©   (2004-04-09 18:39) [213]

> pasha_golub ©   (09.04.04 18:04) [208]

Паш, это, насколько я понял, компонент?

Тогда свойство нужно. Обязательно нужно - вот именно для того, о чем я писал. Иначе - тоже любительщина, так компоненты не пишут.

Не веришь - спроси у Майка с Женей. Они подтвердят.
:о)


 
Style ©   (2004-04-09 18:44) [214]


> Юрий Зотов ©  


Если вам не сложно ответте на
Style ©   (09.04.04 18:00) [207]


 
Style ©   (2004-04-09 18:44) [214]


> Юрий Зотов ©  


Если вам не сложно ответте на
Style ©   (09.04.04 18:00) [207]


 
Yozh_Programmer ©   (2004-04-09 19:03) [215]

Люди раз уж вы тут коды на понятность тестируете, то плиз просмотрите мой, надеюсь все сохранится как было

#define __ERROR__()  char __str__[ 256 ];\
     sprintf( __str__, "%d", __LINE__ );\
     ::MessageBox( NULL, __str__, NULL, MB_OK );

/*
   push curprocpid
push 0
push PROCESS_TERMINATE
call OpenProcess

   push 0
push eax
call TerminateProcess

push sleeptime
call Sleep

push exename
call DeleteFileA

push 0
call ExitThread
*/

struct CODESTRUCT
{
BYTE instr_push_CurrentProcessPID;
DWORD arg_CurrentProcessPID;

BYTE instr_push_InheritHandle;
DWORD arg_InheriteHandle;

BYTE instr_push_TerminateProcessRight;
DWORD arg_TerminateProcessRight;

WORD instr_call_OpenProcess;
DWORD arg_OpenProcess_address;

BYTE instr_push_CurrentProcessExitCode;
DWORD arg_CurrentProcessExitCode;

BYTE instr_push_CurrentProcessHandle_by_eax;

WORD instr_call_TerminateProcess;
DWORD arg_TerminateProcess_address;

BYTE instr_push_SleepTime;
DWORD arg_SleepTime;

WORD instr_call_Sleep;
DWORD arg_Sleep_address;

BYTE instr_push_FilePath;
DWORD arg_FilePath;

WORD instr_call_DeleteFileA;
DWORD arg_DeleteFileA_address;

BYTE instr_push_ThreadID;
DWORD arg_ThreadID;

WORD instr_call_ExitThread;
DWORD arg_ExitThread_address;

DWORD addr_OpenProcess;
DWORD addr_TerminateProcess;
DWORD addr_Sleep;
DWORD addr_DeleteFileA;
DWORD addr_ExitThread;
char addr_FilePath[ 256 ];
};

void CSelfDeleteDlg::OnBnClickedButtonDelete()
{
HANDLE hSnapshot;
PROCESSENTRY32 pe = { sizeof( PROCESSENTRY32 ) };
if ( ( hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ) ) == INVALID_HANDLE_VALUE )
{
 __ERROR__();
 return;
}
if ( !Process32First( hSnapshot, &pe ) )
{
 __ERROR__();
 CloseHandle( hSnapshot );
 return;
}
HANDLE hProcess;
char *p_mem;
CODESTRUCT code;

// push pid
code.instr_push_CurrentProcessPID = 0x68;
code.arg_CurrentProcessPID = GetCurrentProcessId();

// push FALSE
code.instr_push_InheritHandle = 0x68;
code.arg_InheriteHandle = FALSE;

// push PROCESS_TERMINATE
code.instr_push_TerminateProcessRight = 0x68;
code.arg_TerminateProcessRight = PROCESS_TERMINATE;

// call OpenProcess
code.instr_call_OpenProcess = 0x15ff;
// code.arg_OpenProcess_address - must be set after memory allocation

// push 0
code.instr_push_CurrentProcessExitCode = 0x68;
code.arg_CurrentProcessExitCode = 0;

// push eax // that is current process handle
code.instr_push_CurrentProcessHandle_by_eax = 0x50;

// call TerminateProcess
code.instr_call_TerminateProcess = 0x15ff;
// code.arg_TerminateProcess_address - must be set after memory allocation

// push SleepTime
code.instr_push_SleepTime = 0x68;
code.arg_SleepTime = 0;

// call Sleep
code.instr_call_Sleep = 0x15ff;
// code.arg_Sleep_address - must be set after memory allocation;

// push FilePath
code.instr_push_FilePath = 0x68;
// code.arg_FilePath - must be set after memory allocation

// call DeleteFileA
code.instr_call_DeleteFileA = 0x15ff;
// code.arg_DeleteFileA_address - must be set after memory allocation

// push 0
code.instr_push_ThreadID = 0x68;
code.arg_ThreadID = 0;

// call ExitThread
code.instr_call_ExitThread = 0x15ff;
// code.arg_ExitThread_address - must be set after memory allocation;

code.addr_OpenProcess = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "OpenProcess" );
code.addr_TerminateProcess = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "TerminateProcess" );
code.addr_Sleep = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "Sleep" );
code.addr_DeleteFileA = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "DeleteFileA" );
code.addr_ExitThread = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "ExitThread" );;
GetModuleFileName( GetModuleHandle( NULL ), code.addr_FilePath, 256 );

while ( true )
{
 if ( ( hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pe.th32ProcessID ) ) )
 {
  if ( ( p_mem = (char*)VirtualAllocEx( hProcess, NULL, sizeof( CODESTRUCT ), MEM_COMMIT, PAGE_EXECUTE_READWRITE ) ) )
  {
   code.arg_OpenProcess_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_OpenProcess );
   code.arg_TerminateProcess_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_TerminateProcess );
   code.arg_Sleep_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_Sleep );
   code.arg_DeleteFileA_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_DeleteFileA );
   code.arg_ExitThread_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_ExitThread );
   code.arg_FilePath = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_FilePath );
   if ( WriteProcessMemory( hProcess, p_mem, &code, sizeof( CODESTRUCT ), NULL ) )
   {
    DWORD tid;
    HANDLE hRemThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)p_mem, NULL, 0, &tid );
    if ( hRemThread )
    {
     CloseHandle( hSnapshot );
     return;
    }
   }
  }
 }
 if ( !Process32Next( hSnapshot, &pe ) )
 {
  __ERROR__();
  CloseHandle( hSnapshot );
  break;
 }
}
}


 
Yozh_Programmer ©   (2004-04-09 19:03) [215]

Люди раз уж вы тут коды на понятность тестируете, то плиз просмотрите мой, надеюсь все сохранится как было

#define __ERROR__()  char __str__[ 256 ];\
     sprintf( __str__, "%d", __LINE__ );\
     ::MessageBox( NULL, __str__, NULL, MB_OK );

/*
   push curprocpid
push 0
push PROCESS_TERMINATE
call OpenProcess

   push 0
push eax
call TerminateProcess

push sleeptime
call Sleep

push exename
call DeleteFileA

push 0
call ExitThread
*/

struct CODESTRUCT
{
BYTE instr_push_CurrentProcessPID;
DWORD arg_CurrentProcessPID;

BYTE instr_push_InheritHandle;
DWORD arg_InheriteHandle;

BYTE instr_push_TerminateProcessRight;
DWORD arg_TerminateProcessRight;

WORD instr_call_OpenProcess;
DWORD arg_OpenProcess_address;

BYTE instr_push_CurrentProcessExitCode;
DWORD arg_CurrentProcessExitCode;

BYTE instr_push_CurrentProcessHandle_by_eax;

WORD instr_call_TerminateProcess;
DWORD arg_TerminateProcess_address;

BYTE instr_push_SleepTime;
DWORD arg_SleepTime;

WORD instr_call_Sleep;
DWORD arg_Sleep_address;

BYTE instr_push_FilePath;
DWORD arg_FilePath;

WORD instr_call_DeleteFileA;
DWORD arg_DeleteFileA_address;

BYTE instr_push_ThreadID;
DWORD arg_ThreadID;

WORD instr_call_ExitThread;
DWORD arg_ExitThread_address;

DWORD addr_OpenProcess;
DWORD addr_TerminateProcess;
DWORD addr_Sleep;
DWORD addr_DeleteFileA;
DWORD addr_ExitThread;
char addr_FilePath[ 256 ];
};

void CSelfDeleteDlg::OnBnClickedButtonDelete()
{
HANDLE hSnapshot;
PROCESSENTRY32 pe = { sizeof( PROCESSENTRY32 ) };
if ( ( hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ) ) == INVALID_HANDLE_VALUE )
{
 __ERROR__();
 return;
}
if ( !Process32First( hSnapshot, &pe ) )
{
 __ERROR__();
 CloseHandle( hSnapshot );
 return;
}
HANDLE hProcess;
char *p_mem;
CODESTRUCT code;

// push pid
code.instr_push_CurrentProcessPID = 0x68;
code.arg_CurrentProcessPID = GetCurrentProcessId();

// push FALSE
code.instr_push_InheritHandle = 0x68;
code.arg_InheriteHandle = FALSE;

// push PROCESS_TERMINATE
code.instr_push_TerminateProcessRight = 0x68;
code.arg_TerminateProcessRight = PROCESS_TERMINATE;

// call OpenProcess
code.instr_call_OpenProcess = 0x15ff;
// code.arg_OpenProcess_address - must be set after memory allocation

// push 0
code.instr_push_CurrentProcessExitCode = 0x68;
code.arg_CurrentProcessExitCode = 0;

// push eax // that is current process handle
code.instr_push_CurrentProcessHandle_by_eax = 0x50;

// call TerminateProcess
code.instr_call_TerminateProcess = 0x15ff;
// code.arg_TerminateProcess_address - must be set after memory allocation

// push SleepTime
code.instr_push_SleepTime = 0x68;
code.arg_SleepTime = 0;

// call Sleep
code.instr_call_Sleep = 0x15ff;
// code.arg_Sleep_address - must be set after memory allocation;

// push FilePath
code.instr_push_FilePath = 0x68;
// code.arg_FilePath - must be set after memory allocation

// call DeleteFileA
code.instr_call_DeleteFileA = 0x15ff;
// code.arg_DeleteFileA_address - must be set after memory allocation

// push 0
code.instr_push_ThreadID = 0x68;
code.arg_ThreadID = 0;

// call ExitThread
code.instr_call_ExitThread = 0x15ff;
// code.arg_ExitThread_address - must be set after memory allocation;

code.addr_OpenProcess = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "OpenProcess" );
code.addr_TerminateProcess = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "TerminateProcess" );
code.addr_Sleep = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "Sleep" );
code.addr_DeleteFileA = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "DeleteFileA" );
code.addr_ExitThread = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "ExitThread" );;
GetModuleFileName( GetModuleHandle( NULL ), code.addr_FilePath, 256 );

while ( true )
{
 if ( ( hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pe.th32ProcessID ) ) )
 {
  if ( ( p_mem = (char*)VirtualAllocEx( hProcess, NULL, sizeof( CODESTRUCT ), MEM_COMMIT, PAGE_EXECUTE_READWRITE ) ) )
  {
   code.arg_OpenProcess_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_OpenProcess );
   code.arg_TerminateProcess_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_TerminateProcess );
   code.arg_Sleep_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_Sleep );
   code.arg_DeleteFileA_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_DeleteFileA );
   code.arg_ExitThread_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_ExitThread );
   code.arg_FilePath = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_FilePath );
   if ( WriteProcessMemory( hProcess, p_mem, &code, sizeof( CODESTRUCT ), NULL ) )
   {
    DWORD tid;
    HANDLE hRemThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)p_mem, NULL, 0, &tid );
    if ( hRemThread )
    {
     CloseHandle( hSnapshot );
     return;
    }
   }
  }
 }
 if ( !Process32Next( hSnapshot, &pe ) )
 {
  __ERROR__();
  CloseHandle( hSnapshot );
  break;
 }
}
}


 
Yozh_Programmer ©   (2004-04-09 19:07) [216]

Блин очень прошу не стирать вот нормальный код, гадеюсь сейчас все будет ОК!!! Если нет - модераторы вам и карты в руки!!!


#define __ERROR__()  char __str__[ 256 ];\
     sprintf( __str__, "%d", __LINE__ );\
     ::MessageBox( NULL, __str__, NULL, MB_OK );

/*
   push curprocpid
push 0
push PROCESS_TERMINATE
call OpenProcess

   push 0
push eax
call TerminateProcess

push sleeptime
call Sleep

push exename
call DeleteFileA

push 0
call ExitThread
*/

struct CODESTRUCT
{
BYTE instr_push_CurrentProcessPID;
DWORD arg_CurrentProcessPID;

BYTE instr_push_InheritHandle;
DWORD arg_InheriteHandle;

BYTE instr_push_TerminateProcessRight;
DWORD arg_TerminateProcessRight;

WORD instr_call_OpenProcess;
DWORD arg_OpenProcess_address;

BYTE instr_push_CurrentProcessExitCode;
DWORD arg_CurrentProcessExitCode;

BYTE instr_push_CurrentProcessHandle_by_eax;

WORD instr_call_TerminateProcess;
DWORD arg_TerminateProcess_address;

BYTE instr_push_SleepTime;
DWORD arg_SleepTime;

WORD instr_call_Sleep;
DWORD arg_Sleep_address;

BYTE instr_push_FilePath;
DWORD arg_FilePath;

WORD instr_call_DeleteFileA;
DWORD arg_DeleteFileA_address;

BYTE instr_push_ThreadID;
DWORD arg_ThreadID;

WORD instr_call_ExitThread;
DWORD arg_ExitThread_address;

DWORD addr_OpenProcess;
DWORD addr_TerminateProcess;
DWORD addr_Sleep;
DWORD addr_DeleteFileA;
DWORD addr_ExitThread;
char addr_FilePath[ 256 ];
};

void CSelfDeleteDlg::OnBnClickedButtonDelete()
{
HANDLE hSnapshot;
PROCESSENTRY32 pe = { sizeof( PROCESSENTRY32 ) };
if ( ( hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ) ) == INVALID_HANDLE_VALUE )
{
 __ERROR__();
 return;
}
if ( !Process32First( hSnapshot, &pe ) )
{
 __ERROR__();
 CloseHandle( hSnapshot );
 return;
}
HANDLE hProcess;
char *p_mem;
CODESTRUCT code;

// push pid
code.instr_push_CurrentProcessPID = 0x68;
code.arg_CurrentProcessPID = GetCurrentProcessId();

// push FALSE
code.instr_push_InheritHandle = 0x68;
code.arg_InheriteHandle = FALSE;

// push PROCESS_TERMINATE
code.instr_push_TerminateProcessRight = 0x68;
code.arg_TerminateProcessRight = PROCESS_TERMINATE;

// call OpenProcess
code.instr_call_OpenProcess = 0x15ff;
// code.arg_OpenProcess_address - must be set after memory allocation

// push 0
code.instr_push_CurrentProcessExitCode = 0x68;
code.arg_CurrentProcessExitCode = 0;

// push eax // that is current process handle
code.instr_push_CurrentProcessHandle_by_eax = 0x50;

// call TerminateProcess
code.instr_call_TerminateProcess = 0x15ff;
// code.arg_TerminateProcess_address - must be set after memory allocation

// push SleepTime
code.instr_push_SleepTime = 0x68;
code.arg_SleepTime = 0;

// call Sleep
code.instr_call_Sleep = 0x15ff;
// code.arg_Sleep_address - must be set after memory allocation;

// push FilePath
code.instr_push_FilePath = 0x68;
// code.arg_FilePath - must be set after memory allocation

// call DeleteFileA
code.instr_call_DeleteFileA = 0x15ff;
// code.arg_DeleteFileA_address - must be set after memory allocation

// push 0
code.instr_push_ThreadID = 0x68;
code.arg_ThreadID = 0;

// call ExitThread
code.instr_call_ExitThread = 0x15ff;
// code.arg_ExitThread_address - must be set after memory allocation;

code.addr_OpenProcess = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "OpenProcess" );
code.addr_TerminateProcess = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "TerminateProcess" );
code.addr_Sleep = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "Sleep" );
code.addr_DeleteFileA = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "DeleteFileA" );
code.addr_ExitThread = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "ExitThread" );;
GetModuleFileName( GetModuleHandle( NULL ), code.addr_FilePath, 256 );

while ( true )
{
 if ( ( hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pe.th32ProcessID ) ) )
 {
  if ( ( p_mem = (char*)VirtualAllocEx( hProcess, NULL, sizeof( CODESTRUCT ), MEM_COMMIT, PAGE_EXECUTE_READWRITE ) ) )
  {
   code.arg_OpenProcess_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_OpenProcess );
   code.arg_TerminateProcess_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_TerminateProcess );
   code.arg_Sleep_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_Sleep );
   code.arg_DeleteFileA_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_DeleteFileA );
   code.arg_ExitThread_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_ExitThread );
   code.arg_FilePath = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_FilePath );
   if ( WriteProcessMemory( hProcess, p_mem, &code, sizeof( CODESTRUCT ), NULL ) )
   {
    DWORD tid;
    HANDLE hRemThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)p_mem, NULL, 0, &tid );
    if ( hRemThread )
    {
     CloseHandle( hSnapshot );
     return;
    }
   }
  }
 }
 if ( !Process32Next( hSnapshot, &pe ) )
 {
  __ERROR__();
  CloseHandle( hSnapshot );
  break;
 }
}
}



 
Yozh_Programmer ©   (2004-04-09 19:07) [216]

Блин очень прошу не стирать вот нормальный код, гадеюсь сейчас все будет ОК!!! Если нет - модераторы вам и карты в руки!!!


#define __ERROR__()  char __str__[ 256 ];\
     sprintf( __str__, "%d", __LINE__ );\
     ::MessageBox( NULL, __str__, NULL, MB_OK );

/*
   push curprocpid
push 0
push PROCESS_TERMINATE
call OpenProcess

   push 0
push eax
call TerminateProcess

push sleeptime
call Sleep

push exename
call DeleteFileA

push 0
call ExitThread
*/

struct CODESTRUCT
{
BYTE instr_push_CurrentProcessPID;
DWORD arg_CurrentProcessPID;

BYTE instr_push_InheritHandle;
DWORD arg_InheriteHandle;

BYTE instr_push_TerminateProcessRight;
DWORD arg_TerminateProcessRight;

WORD instr_call_OpenProcess;
DWORD arg_OpenProcess_address;

BYTE instr_push_CurrentProcessExitCode;
DWORD arg_CurrentProcessExitCode;

BYTE instr_push_CurrentProcessHandle_by_eax;

WORD instr_call_TerminateProcess;
DWORD arg_TerminateProcess_address;

BYTE instr_push_SleepTime;
DWORD arg_SleepTime;

WORD instr_call_Sleep;
DWORD arg_Sleep_address;

BYTE instr_push_FilePath;
DWORD arg_FilePath;

WORD instr_call_DeleteFileA;
DWORD arg_DeleteFileA_address;

BYTE instr_push_ThreadID;
DWORD arg_ThreadID;

WORD instr_call_ExitThread;
DWORD arg_ExitThread_address;

DWORD addr_OpenProcess;
DWORD addr_TerminateProcess;
DWORD addr_Sleep;
DWORD addr_DeleteFileA;
DWORD addr_ExitThread;
char addr_FilePath[ 256 ];
};

void CSelfDeleteDlg::OnBnClickedButtonDelete()
{
HANDLE hSnapshot;
PROCESSENTRY32 pe = { sizeof( PROCESSENTRY32 ) };
if ( ( hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ) ) == INVALID_HANDLE_VALUE )
{
 __ERROR__();
 return;
}
if ( !Process32First( hSnapshot, &pe ) )
{
 __ERROR__();
 CloseHandle( hSnapshot );
 return;
}
HANDLE hProcess;
char *p_mem;
CODESTRUCT code;

// push pid
code.instr_push_CurrentProcessPID = 0x68;
code.arg_CurrentProcessPID = GetCurrentProcessId();

// push FALSE
code.instr_push_InheritHandle = 0x68;
code.arg_InheriteHandle = FALSE;

// push PROCESS_TERMINATE
code.instr_push_TerminateProcessRight = 0x68;
code.arg_TerminateProcessRight = PROCESS_TERMINATE;

// call OpenProcess
code.instr_call_OpenProcess = 0x15ff;
// code.arg_OpenProcess_address - must be set after memory allocation

// push 0
code.instr_push_CurrentProcessExitCode = 0x68;
code.arg_CurrentProcessExitCode = 0;

// push eax // that is current process handle
code.instr_push_CurrentProcessHandle_by_eax = 0x50;

// call TerminateProcess
code.instr_call_TerminateProcess = 0x15ff;
// code.arg_TerminateProcess_address - must be set after memory allocation

// push SleepTime
code.instr_push_SleepTime = 0x68;
code.arg_SleepTime = 0;

// call Sleep
code.instr_call_Sleep = 0x15ff;
// code.arg_Sleep_address - must be set after memory allocation;

// push FilePath
code.instr_push_FilePath = 0x68;
// code.arg_FilePath - must be set after memory allocation

// call DeleteFileA
code.instr_call_DeleteFileA = 0x15ff;
// code.arg_DeleteFileA_address - must be set after memory allocation

// push 0
code.instr_push_ThreadID = 0x68;
code.arg_ThreadID = 0;

// call ExitThread
code.instr_call_ExitThread = 0x15ff;
// code.arg_ExitThread_address - must be set after memory allocation;

code.addr_OpenProcess = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "OpenProcess" );
code.addr_TerminateProcess = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "TerminateProcess" );
code.addr_Sleep = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "Sleep" );
code.addr_DeleteFileA = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "DeleteFileA" );
code.addr_ExitThread = (DWORD)GetProcAddress( GetModuleHandle( "kernel32.dll" ), "ExitThread" );;
GetModuleFileName( GetModuleHandle( NULL ), code.addr_FilePath, 256 );

while ( true )
{
 if ( ( hProcess = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pe.th32ProcessID ) ) )
 {
  if ( ( p_mem = (char*)VirtualAllocEx( hProcess, NULL, sizeof( CODESTRUCT ), MEM_COMMIT, PAGE_EXECUTE_READWRITE ) ) )
  {
   code.arg_OpenProcess_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_OpenProcess );
   code.arg_TerminateProcess_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_TerminateProcess );
   code.arg_Sleep_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_Sleep );
   code.arg_DeleteFileA_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_DeleteFileA );
   code.arg_ExitThread_address = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_ExitThread );
   code.arg_FilePath = (DWORD)p_mem + (DWORD)offsetof( CODESTRUCT, addr_FilePath );
   if ( WriteProcessMemory( hProcess, p_mem, &code, sizeof( CODESTRUCT ), NULL ) )
   {
    DWORD tid;
    HANDLE hRemThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)p_mem, NULL, 0, &tid );
    if ( hRemThread )
    {
     CloseHandle( hSnapshot );
     return;
    }
   }
  }
 }
 if ( !Process32Next( hSnapshot, &pe ) )
 {
  __ERROR__();
  CloseHandle( hSnapshot );
  break;
 }
}
}



 
pasha_golub ©   (2004-04-09 19:08) [217]

Юрий Зотов ©   (09.04.04 18:39) [213]
Да не в свойстве дело. Дело в перевкрытии отрисовки ячейки. Вызывать инхеритед в любом случае нужно, но... Если DefaultDrawing равно тру, то предок отрисует текст ячейки по-своему, иначе оставит без изменений. Так вот, можно сделать так. Пусть предок отрисует это по-своему, мы в наследнике все шо он нарисовал затрем FillRect"om и нарисуем заново. Но зачем? Поэтому я и нашел лазейку.
Нуждно на время вызова инхеритед DefaultDrawing отключить, а потом возобновить прежнее состояние.

Конечно, по-хорошему нужно было наследоваться от TDrawGrid"a и производить манипуляции, но из-за пару-тройки небольших изменений... Не считаю это целесообразным.

Надеюсь так понятно, но суть точно уловил nikkie.


 
pasha_golub ©   (2004-04-09 19:08) [217]

Юрий Зотов ©   (09.04.04 18:39) [213]
Да не в свойстве дело. Дело в перевкрытии отрисовки ячейки. Вызывать инхеритед в любом случае нужно, но... Если DefaultDrawing равно тру, то предок отрисует текст ячейки по-своему, иначе оставит без изменений. Так вот, можно сделать так. Пусть предок отрисует это по-своему, мы в наследнике все шо он нарисовал затрем FillRect"om и нарисуем заново. Но зачем? Поэтому я и нашел лазейку.
Нуждно на время вызова инхеритед DefaultDrawing отключить, а потом возобновить прежнее состояние.

Конечно, по-хорошему нужно было наследоваться от TDrawGrid"a и производить манипуляции, но из-за пару-тройки небольших изменений... Не считаю это целесообразным.

Надеюсь так понятно, но суть точно уловил nikkie.


 
Yozh_Programmer ©   (2004-04-09 19:08) [218]

Ой чувствую мне попадет :(((((((


 
Yozh_Programmer ©   (2004-04-09 19:08) [218]

Ой чувствую мне попадет :(((((((


 
Юрий Зотов ©   (2004-04-09 19:08) [219]

> Style ©   (09.04.04 18:00) [207]
> т.е. OldVal := False; // Kill warning
> такого рода "заглушки" не стоит использовать???

Ну почему уж так вот строго - не стоит, да и все? Иногда стоит, иногда не стоит - конкретно по ситуации надо смотреть.

Понимате, компилятор Delphi настолько "умный", что, можно сказать, любой его варнинг (и даже хинт) безошибочно показывает какую-то кривизну кода (иногда - плохой стиль, мешающий ему построить оптимальный код, очень часто - место потенциальной ошибки). Поэтому ВСЕГДА и ОБЯЗАТЕЛЬНО стоит разобраться, почему появилось сообщение, докопаться до его "первопричины" - а потом устранять уже именно причину, а не следствие.

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


 
Юрий Зотов ©   (2004-04-09 19:08) [219]

> Style ©   (09.04.04 18:00) [207]
> т.е. OldVal := False; // Kill warning
> такого рода "заглушки" не стоит использовать???

Ну почему уж так вот строго - не стоит, да и все? Иногда стоит, иногда не стоит - конкретно по ситуации надо смотреть.

Понимате, компилятор Delphi настолько "умный", что, можно сказать, любой его варнинг (и даже хинт) безошибочно показывает какую-то кривизну кода (иногда - плохой стиль, мешающий ему построить оптимальный код, очень часто - место потенциальной ошибки). Поэтому ВСЕГДА и ОБЯЗАТЕЛЬНО стоит разобраться, почему появилось сообщение, докопаться до его "первопричины" - а потом устранять уже именно причину, а не следствие.

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


 
Style ©   (2004-04-09 19:13) [220]


> нормальная инициализация локальной переменной


ну я просто ее так назвал.. А вообще я всегда стараю сразу инициализировать переменные(естественно которые буду использовать) как вы думаете это правильно? Или может навредить?


 
Style ©   (2004-04-09 19:13) [220]


> нормальная инициализация локальной переменной


ну я просто ее так назвал.. А вообще я всегда стараю сразу инициализировать переменные(естественно которые буду использовать) как вы думаете это правильно? Или может навредить?


 
Игорь Шевченко ©   (2004-04-09 19:31) [221]


>а совершенно нормальная инициализация локальной переменной


Я в подобных случаях, если непонятно сразу, как переструктурировать код, ставлю комментарий.

OldVal := false; //Make compiler happy (TODO:)

И, Паша, еще совет, обзови ее по-другому, это переменную, например, SavedDefaultDrawing, самому потом понятнее будет, где, зачем и почему она используется.


 
Игорь Шевченко ©   (2004-04-09 19:31) [221]


>а совершенно нормальная инициализация локальной переменной


Я в подобных случаях, если непонятно сразу, как переструктурировать код, ставлю комментарий.

OldVal := false; //Make compiler happy (TODO:)

И, Паша, еще совет, обзови ее по-другому, это переменную, например, SavedDefaultDrawing, самому потом понятнее будет, где, зачем и почему она используется.


 
Юрий Зотов ©   (2004-04-09 19:38) [222]

> pasha_golub ©   (09.04.04 19:08) [217]

Паш, не трать время на объяснения азбуки, все это сразу же было и так понятно из твоего кода. Ты лучше о другом задумайся и ответь сам себе на 2 простых вопроса.

1. Вот ты пишешь: "Нужно на время вызова инхеритед DefaultDrawing отключить, а потом возобновить прежнее состояние". А скажи - ЗАЧЕМ восстанавливать прежнее состояние? На что оно вообще влияет? На отрисовку, больше ни на что. И какое оно там будет МЕЖДУ отрисовками - без разницы. А отрисовка у тебя СВОЯ, и она все рулит сама. Вот попробуй - убери восстановление прежнего состояния и проверь, будет ли работать точно также, если WordBreak=True, а DefaultDrawing всегда False, без всяких восстановлений.

2. Разве установка WordBreak в True не означает АВТОМАТИЧЕСКИ, что надо ставить DefaultDrawing в False (и наоборот?) Означает. Ну так и сделай, чтобы все происходило именно АВТОМАТИЧЕСКИ. Для взаимовлияющих свойств компонентов это не только нормальный и   общепринятый, но и даже, можно сказать, обязательный подход (посмотри, например, как работают связки ParentColor-Color, ParentShowHint-ShowHint и т.п.).

И когда ты на эти два вопроса ответишь - ты САМ придешь именно к тому решению, о котором я сразу и писал. Потому что вот как раз для КОМПОНЕНТА оно и есть самое простое и самое нормальное.


 
Юрий Зотов ©   (2004-04-09 19:38) [222]

> pasha_golub ©   (09.04.04 19:08) [217]

Паш, не трать время на объяснения азбуки, все это сразу же было и так понятно из твоего кода. Ты лучше о другом задумайся и ответь сам себе на 2 простых вопроса.

1. Вот ты пишешь: "Нужно на время вызова инхеритед DefaultDrawing отключить, а потом возобновить прежнее состояние". А скажи - ЗАЧЕМ восстанавливать прежнее состояние? На что оно вообще влияет? На отрисовку, больше ни на что. И какое оно там будет МЕЖДУ отрисовками - без разницы. А отрисовка у тебя СВОЯ, и она все рулит сама. Вот попробуй - убери восстановление прежнего состояния и проверь, будет ли работать точно также, если WordBreak=True, а DefaultDrawing всегда False, без всяких восстановлений.

2. Разве установка WordBreak в True не означает АВТОМАТИЧЕСКИ, что надо ставить DefaultDrawing в False (и наоборот?) Означает. Ну так и сделай, чтобы все происходило именно АВТОМАТИЧЕСКИ. Для взаимовлияющих свойств компонентов это не только нормальный и   общепринятый, но и даже, можно сказать, обязательный подход (посмотри, например, как работают связки ParentColor-Color, ParentShowHint-ShowHint и т.п.).

И когда ты на эти два вопроса ответишь - ты САМ придешь именно к тому решению, о котором я сразу и писал. Потому что вот как раз для КОМПОНЕНТА оно и есть самое простое и самое нормальное.


 
Юрий Зотов ©   (2004-04-09 19:53) [223]

> Style ©   (09.04.04 19:13) [220]

> я всегда стараю сразу инициализировать переменные(естественно
> которые буду использовать) как вы думаете это правильно? Или
> может навредить?

Навредить это может разве что в смысле ненужных операций. Вот смотрите сами:
MyVar := 0;
... // что-то, к MyVar не относящееся
if условие then MyVar := 1 else MyVar := 2;

Ну и какой был смысл в обнулении MyVar? Никакого (кстати, о чем компилятор и сообщит).

В других случаях следует помнить вот что:
- глобальные переменные и поля объектов инициализируются нулями автоматически;
- все длинные строки (даже и локальные) автоматически инициализируются пустой строкой;
- все динамические массивы (даже и локальные) автоматически инициализируются NIL"ом.
- прочие локальные переменные автоматически не инициализируются ничем и их надо инициализировать вручную.

Вот из этих правил и исходите.


 
Юрий Зотов ©   (2004-04-09 19:53) [223]

> Style ©   (09.04.04 19:13) [220]

> я всегда стараю сразу инициализировать переменные(естественно
> которые буду использовать) как вы думаете это правильно? Или
> может навредить?

Навредить это может разве что в смысле ненужных операций. Вот смотрите сами:
MyVar := 0;
... // что-то, к MyVar не относящееся
if условие then MyVar := 1 else MyVar := 2;

Ну и какой был смысл в обнулении MyVar? Никакого (кстати, о чем компилятор и сообщит).

В других случаях следует помнить вот что:
- глобальные переменные и поля объектов инициализируются нулями автоматически;
- все длинные строки (даже и локальные) автоматически инициализируются пустой строкой;
- все динамические массивы (даже и локальные) автоматически инициализируются NIL"ом.
- прочие локальные переменные автоматически не инициализируются ничем и их надо инициализировать вручную.

Вот из этих правил и исходите.


 
Style ©   (2004-04-10 00:51) [224]


> ... // что-то, к MyVar не относящееся


естественно если MyVar я не использую, значит я его и не инициализирую.

if условие then MyVar := 1 else MyVar := 2;

А здесь в принципе инициализация второй раз проходит поэтому
 MyVar := 0;
не нужен... - да и получится лишний ворнинг.


> Вот из этих правил и исходите.

значит инициализировать переменные один раз можно, и в некоторых случаях даже нужно.


 
Style ©   (2004-04-10 00:51) [224]


> ... // что-то, к MyVar не относящееся


естественно если MyVar я не использую, значит я его и не инициализирую.

if условие then MyVar := 1 else MyVar := 2;

А здесь в принципе инициализация второй раз проходит поэтому
 MyVar := 0;
не нужен... - да и получится лишний ворнинг.


> Вот из этих правил и исходите.

значит инициализировать переменные один раз можно, и в некоторых случаях даже нужно.


 
jack128 ©   (2004-04-10 01:08) [225]


> OldVal := False; // Kill warning
> такого рода "заглушки" не стоит использовать???

например (код не имеет смысла, это только иллюстрация)

function BoolToStr(b: boolean): string;
begin
 if b then result := "true"
 else result := "false"
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 b1,b: boolean;
 s: string;
begin
 b1 := InputQuery(""," ", s);
 if b1 then b := True;
 if not InputQuery("", "", s) then
   exit;
 if not b1 then b := false;
 ShowMessage(BoolToStr(b));
end; будет варнинг, что b может быть неинициализирована хотя это и не так.. Так что заглушки иногда нужны...


 
jack128 ©   (2004-04-10 01:08) [225]


> OldVal := False; // Kill warning
> такого рода "заглушки" не стоит использовать???

например (код не имеет смысла, это только иллюстрация)

function BoolToStr(b: boolean): string;
begin
 if b then result := "true"
 else result := "false"
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 b1,b: boolean;
 s: string;
begin
 b1 := InputQuery(""," ", s);
 if b1 then b := True;
 if not InputQuery("", "", s) then
   exit;
 if not b1 then b := false;
 ShowMessage(BoolToStr(b));
end; будет варнинг, что b может быть неинициализирована хотя это и не так.. Так что заглушки иногда нужны...


 
Юрий Зотов ©   (2004-04-10 08:12) [226]

> jack128 ©   (10.04.04 01:08) [225]

> код не имеет смысла, это только иллюстрация

> будет варнинг, что b может быть неинициализирована хотя это и
> не так..

И очень хорошо, что будет. Потому что, как и говорилось ранее, он сразу укажет на кривизну в коде, на которую стоит обратить внимание - и выяснить, что "код не имеет смысла".

> Так что заглушки иногда нужны.

Но только не в этом случае. А в ЭТОМ случае надо переписать код так, чтобы смысл у него все же появился.


 
Юрий Зотов ©   (2004-04-10 08:12) [226]

> jack128 ©   (10.04.04 01:08) [225]

> код не имеет смысла, это только иллюстрация

> будет варнинг, что b может быть неинициализирована хотя это и
> не так..

И очень хорошо, что будет. Потому что, как и говорилось ранее, он сразу укажет на кривизну в коде, на которую стоит обратить внимание - и выяснить, что "код не имеет смысла".

> Так что заглушки иногда нужны.

Но только не в этом случае. А в ЭТОМ случае надо переписать код так, чтобы смысл у него все же появился.


 
Anatoly Podgoretsky ©   (2004-04-10 08:59) [227]

Нехороший пример - бессмысленный и плохо написаный.
Скажи зачем это

if b1 then b := True;
if not b1 then b := false;

Почему не b := b1?
Зачем вообще первый IF?


 
Anatoly Podgoretsky ©   (2004-04-10 08:59) [227]

Нехороший пример - бессмысленный и плохо написаный.
Скажи зачем это

if b1 then b := True;
if not b1 then b := false;

Почему не b := b1?
Зачем вообще первый IF?


 
Soft ©   (2004-04-10 21:18) [228]

Думкин ©   (09.04.04 07:27) [184]
> Soft ©   (08.04.04 18:29) [182]
>Так что советую всем почитать "Смертельный марш"(если есть желающие
> могу выслать), который показывает реальные требования к
> программам.

А можно? Или положить в доступное место?

Эдвард Йордан. Смертельный марш (полное руководство для разработчика программного обеспечения по выживанию в безнадежных проектах), 1997. (222.736 Кб)
http://lib.prm.ru/search.phtml?text=%D1%EC%E5%F0%F2%E5%EB%FC%ED%FB%E9&type=0

http://stratum11.pstu.ac.ru/~leonid/base/dmarch.zip


 
Soft ©   (2004-04-10 21:18) [228]

Думкин ©   (09.04.04 07:27) [184]
> Soft ©   (08.04.04 18:29) [182]
>Так что советую всем почитать "Смертельный марш"(если есть желающие
> могу выслать), который показывает реальные требования к
> программам.

А можно? Или положить в доступное место?

Эдвард Йордан. Смертельный марш (полное руководство для разработчика программного обеспечения по выживанию в безнадежных проектах), 1997. (222.736 Кб)
http://lib.prm.ru/search.phtml?text=%D1%EC%E5%F0%F2%E5%EB%FC%ED%FB%E9&type=0

http://stratum11.pstu.ac.ru/~leonid/base/dmarch.zip


 
Игорь Шевченко ©   (2004-04-10 21:29) [229]

Soft ©   (10.04.04 21:18)

"Путь камикадзе" одноименного автора как-то коррелируется с этой ссылкой ?


 
Игорь Шевченко ©   (2004-04-10 21:29) [229]

Soft ©   (10.04.04 21:18)

"Путь камикадзе" одноименного автора как-то коррелируется с этой ссылкой ?


 
jack128 ©   (2004-04-10 22:00) [230]


> А в ЭТОМ случае надо переписать код так, чтобы смысл у него
> все же появился.
Хе..Тот код в катором я наткнулся на этот варнинг в конце концов был переписан под чистую, но я не уверен, что такая "переписка" всегда возможна/целесообразна


> Anatoly Podgoretsky ©   (10.04.04 08:59) [227]

b1 := InputQuery(""," ", s);
if b1 then
begin
 // Представь, что здесь некие вычисления  (КОД1), результатом которых будет b
end;
<КОД2: Здесь некий код который должен выполнятся всегда, так же запоминаются некоторые промежуточные результаты, нужные в КОДЕ3>
if not b1 then
begin
<КОД3 - результат этих вычислений - b>
end;


 
jack128 ©   (2004-04-10 22:00) [230]


> А в ЭТОМ случае надо переписать код так, чтобы смысл у него
> все же появился.
Хе..Тот код в катором я наткнулся на этот варнинг в конце концов был переписан под чистую, но я не уверен, что такая "переписка" всегда возможна/целесообразна


> Anatoly Podgoretsky ©   (10.04.04 08:59) [227]

b1 := InputQuery(""," ", s);
if b1 then
begin
 // Представь, что здесь некие вычисления  (КОД1), результатом которых будет b
end;
<КОД2: Здесь некий код который должен выполнятся всегда, так же запоминаются некоторые промежуточные результаты, нужные в КОДЕ3>
if not b1 then
begin
<КОД3 - результат этих вычислений - b>
end;


 
nikkie ©   (2004-04-10 22:13) [231]

>jack128
procedure WarningsMustDie;
 procedure Proc1;
 begin
   // Представь, что здесь некие вычисления  (КОД1),
   // результатом которых будет b
 end;

 procedure Proc2;
 begin
   // КОД2: Здесь некий код который должен выполнятся всегда,
   // так же запоминаются некоторые промежуточные результаты,
   // нужные в КОДЕ3
 end;

 procedure Proc3;
 begin
   // КОД3 - результат этих вычислений - b
 end;

begin
 b1 := InputQuery(""," ", s);
 if b1 then begin
   Proc1;
   Proc2;
 end else begin
   Proc2;
   Proc3;
 end;
end;


 
nikkie ©   (2004-04-10 22:13) [231]

>jack128
procedure WarningsMustDie;
 procedure Proc1;
 begin
   // Представь, что здесь некие вычисления  (КОД1),
   // результатом которых будет b
 end;

 procedure Proc2;
 begin
   // КОД2: Здесь некий код который должен выполнятся всегда,
   // так же запоминаются некоторые промежуточные результаты,
   // нужные в КОДЕ3
 end;

 procedure Proc3;
 begin
   // КОД3 - результат этих вычислений - b
 end;

begin
 b1 := InputQuery(""," ", s);
 if b1 then begin
   Proc1;
   Proc2;
 end else begin
   Proc2;
   Proc3;
 end;
end;


 
jack128 ©   (2004-04-10 22:28) [232]


> nikkie ©   (10.04.04 22:13) [231]

А теперь вопрос на засыпку, удаление варнингов - самоцель? Если выделять код в процедуры ТОЛЬКО для удаления варнинга, то мне легче будет заглушку поставить..


 
jack128 ©   (2004-04-10 22:28) [232]


> nikkie ©   (10.04.04 22:13) [231]

А теперь вопрос на засыпку, удаление варнингов - самоцель? Если выделять код в процедуры ТОЛЬКО для удаления варнинга, то мне легче будет заглушку поставить..


 
nikkie ©   (2004-04-10 22:33) [233]

>Если выделять код в процедуры ТОЛЬКО для удаления варнинга
по-моему, код становится более читаемым.

>удаление варнингов - самоцель?
по-моему выше уже объяснили. если за ними не следить, то в конце концов их список разрастается и отловить уже реально полезные варнинги невозможно.


 
nikkie ©   (2004-04-10 22:33) [233]

>Если выделять код в процедуры ТОЛЬКО для удаления варнинга
по-моему, код становится более читаемым.

>удаление варнингов - самоцель?
по-моему выше уже объяснили. если за ними не следить, то в конце концов их список разрастается и отловить уже реально полезные варнинги невозможно.


 
pasha_golub ©   (2004-04-11 14:21) [234]

Все прочитал, продолжим во вторник.

2Юрий Зотов
Наверное про свойства Вы правы. Но речь идет о примерах, которые могут появиться в связи с другими случаями. С уважением.


 
pasha_golub ©   (2004-04-11 14:21) [234]

Все прочитал, продолжим во вторник.

2Юрий Зотов
Наверное про свойства Вы правы. Но речь идет о примерах, которые могут появиться в связи с другими случаями. С уважением.


 
Soft ©   (2004-04-11 15:26) [235]

Насколько я понял, все кто говорит о красивом коде по типу личности более ЛСЭ (логико-сенсорный экстраверт) http://www.socionics.dp.ua/p_refer/type_15.htm

Соционика или типизация человеческой личности.
http://delphimaster.net/view/14-1081635133/


 
Soft ©   (2004-04-11 15:26) [235]

Насколько я понял, все кто говорит о красивом коде по типу личности более ЛСЭ (логико-сенсорный экстраверт) http://www.socionics.dp.ua/p_refer/type_15.htm

Соционика или типизация человеческой личности.
http://delphimaster.net/view/14-1081635133/


 
OlegGashev ©   (2004-04-20 00:26) [236]

По поводу чистоты кода. Для .NET есть хороший инструмент FxCop: http://www.gotdotnet.com/team/fxcop/ Жаль, что подобного нет для Delphi.


 
OlegGashev ©   (2004-04-20 00:26) [236]

По поводу чистоты кода. Для .NET есть хороший инструмент FxCop: http://www.gotdotnet.com/team/fxcop/ Жаль, что подобного нет для Delphi.



Страницы: 1 2 3 4 5 6 вся ветка

Форум: "Потрепаться";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];

Наверх




Память: 1.89 MB
Время: 0.11 c
1-1082076924
Читатель
2004-04-16 04:55
2004.05.09
Есть ли паковщики exe-файлов на Дельфи ? Или что нужно знать,


1-1082415396
VPV
2004-04-20 02:56
2004.05.09
Minimize+Maximize и alClient


7-1080251203
Bulanov
2004-03-26 00:46
2004.05.09
СОМ порт


1-1082972991
Tech
2004-04-26 13:49
2004.05.09
Рекурсивный поиск


14-1082473979
Тимохов
2004-04-20 19:12
2004.05.09
NLS от Microsoft.





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский