Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 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.49 MB
Время: 0.03 c
14-1118603404
focor
2005-06-12 23:10
2005.07.11
+++Windows MOBILE+++


3-1117176187
MakNik
2005-05-27 10:43
2005.07.11
Пересечение промежутков дат


14-1118811322
Crow
2005-06-15 08:55
2005.07.11
Темы для диплома


4-1116153069
TwisteR(TFSoft)
2005-05-15 14:31
2005.07.11
Format в WinAPI


1-1118563903
acsoft
2005-06-12 12:11
2005.07.11
Возможно ли считать свой собственный код?