![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблема с буфером для вывода текста в различных режимах
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)).