Текущий архив: 2005.07.11;
Скачать: CL | DM;
ВнизПроблема с буфером для вывода текста в различных режимах Найти похожие ветки
← →
LaMaX © (2005-05-14 13:19) [0]Здраствуйте проблема в следующем при запуске программы прогрмма выодит данные для режима 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;
← →
begin...end © (2005-05-14 13:39) [1]> LaMaX © (14.05.05 13:19)
Перед вызовом wsprintf под буфер szBuffer должна быть выделена память в размере не менее количество_символов_которое_поместит_в_строку_функция_wsprintf + 1. А Вы выделяете буферу тоько 4 байта (sizeof(szBuffer)).
← →
LaMaX © (2005-05-14 19:19) [2]Выделил память больше вес равно та же проблема.
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.
То же самое и с другими режимами отображения.
← →
VMcL © (2005-05-14 20:26) [3]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.
← →
VMcL © (2005-05-14 20:27) [4]>>VMcL © (14.05.05 20:26) [3]
Забыл написать - это о wsprintf.
← →
VMcL © (2005-05-14 20:27) [5]>>VMcL © (14.05.05 20:26) [3]
Забыл написать - это о wsprintf.
← →
GuAV © (2005-05-14 20:49) [6]
function wsprintf(Output: PChar; Format: PChar): Integer;
cdecl; varargs; external user32 name "wsprintfA";
← →
LaMaX © (2005-05-15 19:52) [7]Нет благодаря
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.
← →
LaMaX © (2005-05-15 20:25) [8]Все вышеприведенные функциия находятся в strsafe.lib а это насколько я понял подключаемая библиотека С++
← →
VMcL © (2005-05-15 21:37) [9]Чем не устраивает SysUtils.Format?
Страницы: 1 вся ветка
Текущий архив: 2005.07.11;
Скачать: CL | DM;
Память: 0.48 MB
Время: 0.039 c