Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Проблема с буфером для вывода текста в различных режимах


LaMaX ©   (2005-05-14 13:19:00) 

Здраствуйте проблема в следующем при запуске программы прогрмма выодит данные для режима MM_TEXT на этом и заканчивается, не выводя жругих режимов.При попытке вывести другие режимы, например
MM_LOMETRIC программа матерится на неправильное обращение к памяти.  
Все выводы текста и передача параметров режима отображения передаются в процедуру Show.
procedure Show(winc:HWND;shdc:HDC; xText:Integer; yText:Integer; iMapMode:Integer; szMapMode:PChar);
var
szBuffer:PChar;
rect:TRect;
pt:TPoint;
begin
SaveDC(shdc);
SetMapMode(shdc, iMapMode);
GetClientRect(winc, rect);
pt.X:=rect.Left;
pt.Y:=rect.Top;
DPtoLP(shdc,pt,2);
RestoreDC(shdc, -1);
GetMem(szBuffer,sizeof(szBuffer));
TextOut(shdc, xText, yText, szBuffer,wsprintf(szBuffer,'%-20s %7d %7d %7d %7d',szMapMode, rect.Left, rect.Right, rect.Top, rect.Bottom));
FreeMem(szBuffer,sizeof(szBuffer));
end;

При этом переопределена функция wsprint под свои нужды, в языке С используется поцедура sprintf.

function wsprintf( lpOut: LPSTR; lpFmt: LPCTSTR; p:PChar; X,Y,W,H:Integer):Integer;
stdcall; external 'user32.dll' name 'wsprintfA';

Для того чтобы передать значения в переменную szBuffer выделяю для нее память.Я думаю что возможно проблема выделения памяти для переменной szBuffer  в процедуре Show. Кто подскажет как решить данную проблему.
GetMem(szBuffer,sizeof(szBuffer));
TextOut(shdc, xText, yText, szBuffer,wsprintf(szBuffer,'%-20s %7d %7d %7d %7d',szMapMode, rect.Left, rect.Right, rect.Top, rect.Bottom));
FreeMem(szBuffer,sizeof(szBuffer));

Ниже приведен кусок кода программы:

function wsprintf( lpOut: LPSTR; lpFmt: LPCTSTR; p:PChar; X,Y,W,H:Integer):Integer;
stdcall; external 'user32.dll' name 'wsprintfA';

procedure Show(winc:HWND;shdc:HDC; xText:Integer; yText:Integer; iMapMode:Integer; szMapMode:PChar);
var
szBuffer:PChar;
rect:TRect;
pt:TPoint;
begin
SaveDC(shdc);
SetMapMode(shdc, iMapMode);
GetClientRect(winc, rect);
pt.X:=rect.Left;
pt.Y:=rect.Top;
DPtoLP(shdc,pt,2);
RestoreDC(shdc, -1);
GetMem(szBuffer,sizeof(szBuffer));
TextOut(shdc, xText, yText, szBuffer,wsprintf(szBuffer,'%-20s %7d %7d %7d %7d',szMapMode, rect.Left, rect.Right, rect.Top, rect.Bottom));
FreeMem(szBuffer,sizeof(szBuffer));
end;

function WndProc(win:HWND; iMsg:Integer; wParam:WPARAM; lParam:LPARAM):LRESULT; stdcall;
var
myhdc:HDC;
ps:TPaintStruct;
tm:TTextMetric;
begin
   CASE iMsg of

      WM_CREATE:
               begin
                myhdc:= GetDC(win);
                SelectObject(myhdc, GetStockObject(SYSTEM_FIXED_FONT));
                GetTextMetrics(myhdc, tm);
                cxChar:= tm.tmAveCharWidth;
                cyChar:= tm.tmHeight + tm.tmExternalLeading;

                ReleaseDC(win, myhdc);
                Result:=0;
               end;

      WM_PAINT:
               begin
                myhdc:= BeginPaint(win, ps);
      SelectObject(myhdc, GetStockObject(SYSTEM_FIXED_FONT));
      SetMapMode(myhdc, MM_ANISOTROPIC);
      SetWindowExtEx(myhdc, 1,1, nil);
      SetViewportExtEx(myhdc, cxChar, cyChar, nil);

      TextOut(myhdc, 1, 1, szHeading,length(szHeading));
      TextOut(myhdc, 1, 2, szUndLine,length(szUndLine));
      Show(win, myhdc, 1, 3, MM_TEXT, 'TEXT(pixels)');
      Show(win, myhdc, 1, 4, MM_LOMETRIC, 'LOMETRIC(1 mm)');
      Show(win, myhdc, 1, 5, MM_HIMETRIC, 'HIMETRIC(.01 mm)');

                 EndPaint(win, ps);
                Result:= 0;

               end;
      WM_DESTROY:
               begin
                PostQuitMessage(0);
                Result:= 0;
               end;
      else
       Result:= DefWindowProc(win, iMsg, wParam, lParam);

   end;//end case
end;


VMcL   (2005-05-15 21:37:00) [1]

Чем не устраивает SysUtils.Format?


LaMaX   (2005-05-15 20:25:00) [2]

Все вышеприведенные функциия находятся в strsafe.lib а это насколько я понял подключаемая библиотека С++


LaMaX   (2005-05-15 19:52:00) [3]

Нет благодаря
function wsprintf(Output: PChar; Format: PChar): Integer;
cdecl; varargs; external user32 name 'wsprintfA';

Выводит и MM_TEXT и MM_LOMETRIC затем появляется та же ошибка. Насколько я понял из вышесказанного формат %s приводит к переполнению буфера.
Кто скажет как можно будет подключить к Дельфям какую либо из приведенных функций StringCbPrintf, StringCbPrintfEx, StringCbVPrintf, StringCbVPrintfEx, StringCchPrintf, StringCchPrintfEx, StringCchVPrintf, or StringCchVPrintfEx.


GuAV   (2005-05-14 20:49:00) [4]

function wsprintf(Output: PChar; Format: PChar): Integer;
 cdecl; varargs; external user32 name 'wsprintfA';


VMcL   (2005-05-14 20:27:00) [5]

>> VMcL ©   (14.05.05 20:26) [3]

Забыл написать - это о wsprintf.


VMcL   (2005-05-14 20:27:00) [6]

>> VMcL ©   (14.05.05 20:26) [3]

Забыл написать - это о wsprintf.


VMcL   (2005-05-14 20:26:00) [7]

1.
Note  It is important to note that wsprintf uses the C calling convention (_cdecl), rather than the standard call (_stdcall) calling convention. As a result, it is the responsibility of the calling process to pop arguments off the stack, and arguments are pushed on the stack from right to left. In C-language modules, the C compiler performs this task.

2.
Security Alert
Using this function incorrectly can compromise the security of your application. The string returned in lpOut is not guaranteed to be NULL-terminated. Also, avoid the %s format -- it can lead to a buffer overrun. If an access violation occurs it causes a denial of service against your application. In the worse case, an attacker can inject executable code. Consider using one of the following alternatives: StringCbPrintf, StringCbPrintfEx, StringCbVPrintf, StringCbVPrintfEx, StringCchPrintf, StringCchPrintfEx, StringCchVPrintf, or StringCchVPrintfEx. You should review Security Considerations: Windows User Interface before continuing.


LaMaX   (2005-05-14 19:19:00) [8]

Выделил память больше вес равно та же проблема.

GetMem(szBuffer,SizeOf(szBuffer) * 20);

Дело в том что он выводит режим MM_TEXT. Без всяких ошибок как кажется.  
Если  закоментировать строку выводящую режим MM_TEXT

      TextOut(myhdc, 1, 1, szHeading,length(szHeading) - 1);
      TextOut(myhdc, 1, 2, szUndLine,length(szUndLine) - 1);
      //Show(win, myhdc, 1, 3, MM_TEXT, 'TEXT(pixels)');
      Show(win, myhdc, 1, 4, MM_LOMETRIC, 'LOMETRIC(.1 mm)');
      Show(win, myhdc, 1, 5, MM_HIMETRIC, 'HIMETRIC(.01 mm)');
      EndPaint(win, ps);
      Result:= 0;

Выводит строку с MM_LOMETRIC  и выдает сообщение о RuntimeError 216 at .  При подключении модуля SySUtils впслывает исключение Exception EAccess Violation in module .... at FEFDF3EC.
Access violation at address FEFE03EC. Read of address FEFE03EC.

То же самое и с другими режимами отображения.


begin...end   (2005-05-14 13:39:00) [9]

> LaMaX ©   (14.05.05 13:19)

Перед вызовом wsprintf под буфер szBuffer должна быть выделена память в размере не менее количество_символов_которое_поместит_в_строку_функция_wsprintf + 1. А Вы выделяете буферу тоько 4 байта (sizeof(szBuffer)).


Наверх

Титульная страница Поиск, карта сайта Написать письмо