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

Вниз

Hе могу найти ошибку   Найти похожие ветки 

 
Aquaform   (2002-09-08 16:29) [0]

Где-то в коде ошибка. Где - не пойму.
Судя по всему это из-за Pchar"ов долбанных...
А точнее из-за неправильной работы функции wvsprintf

program Project1;
{$R *.RES}

uses
windows,
messages;

var
Instance: HWND;
WindowClass: TWNDClass;
Handle: HWND;
msg: TMsg;

procedure ExitProgram;
begin
Halt;
end;

//--------------------------------------------------------------
//САМОЕ ГЛАВНОЕ
//Функция обработки сообщений...
function WindowProc(Hwn,msg,wpr,lpr:longint):longint;stdcall;
var P1, P2, P3:Pchar;
x,y:integer;
begin
result:=defwindowproc(hwn,msg,wpr,lpr);
if msg=wm_destroy then ExitProgram;
if (msg=WM_LBUTTONUP) then //Если отпущена левая кнопка мыши
begin
new(P1); // Выделяется память под PChar"ы
new(P2);
new(P3);
try
P1:="x="; // P1= "x="
x:=loword(lpr); // x и y - координаты точки, где отпустили
y:=hiword(lpr); // кнопку мыши

wvsprintf(P2,"%i",@x); // P2= "35" - допустим
P1:=lStrCat(P1,P2); // P1= "x=35"
P1:=lStrCat(P1," y="); // P1= "x=35 y="
wvsprintf(P3,"%i",@y); // По идее, P3= "65" (например), но
// на самом деле P3 =" y=" (где-то так)

P1:=lStrCat(P1,P3); // Если б все было ок, то P1= "x=35 y=65"
messagebox(handle,P1,"Координаты курсора",mb_ok); //Сообщение о координатах
// Выводится на экран
finally
dispose(P1); // При вызове dispose происходит Run-Time Error
dispose(P2);
dispose(P3);
end;
end;

end;
//------------------------------------------------------------------

BEGIN

instance:=GetModuleHandle(nil);
Windowclass.style:=CS_HRedraw or CS_VRedraw;
WIndowClass.lpfnWndProc :=@WindowProc;
WindowClass.hInstance :=instance;
Windowclass.hbrBackground:=COLOR_BACKGROUND;
WindowClass.lpszClassName:="SCL";
Windowclass.hCursor :=LoadCursor(0,IDC_ARROW);

RegisterClass(WindowClass);

Handle:=CreateWindowEx(0,"SCL","Моя прога на WinApi",WS_SYSMENU or ws_maximizebox or WS_MINIMIZEBOX,(GetSystemMetrics(SM_CXSCREEN) div 2)-150,(GetSystemMetrics(SM_CYSCREEN) div 2)-150,300,300,0,0,instance,nil);

showwindow(handle,SW_SHOW);

while (GetMessage(msg,0,0,0)) do
begin
translatemessage(msg);
dispatchmessage(msg);
end;
end.



Ошибки обoзначены в комментариях к коду.

Может быть написал криво, но если вставить все это в Delphi и посмотреть на результат, думаю, все станет понятно.

Если кому влом разбираться, можно сделать так. Дайте мне исходник программы на winapi, с использованием только windows и messages. Чтобы создавалось окно, на него тыкаешь мышкой и всплывало сообщение, где написаны координаты точки куда ткнули мышкой вида "x=45 y=76"

Заранее спасибо.


 
Anatoly Podgoretsky   (2002-09-08 16:47) [1]

По крайней мере ты не выделил память под PChar


 
ZZ   (2002-09-08 16:56) [2]

Ошибки обoзначены в комментариях к коду.
Как в воду глядел :)
Что (и скока) ты хочешь получить после вызова
new(P1); // Выделяется память под PChar"ы


 
Aquaform   (2002-09-08 20:04) [3]

Я пробовал и через Getmem, freemem.

А насчет new, dispose. Насколько я читал в функции new можно указать размер выделяемой памяти, а можно просто написать new(P1). Тогда для P1 выделится стандартный размер...


 
Aquaform   (2002-09-08 20:14) [4]

А насчет new, dispose. Насколько я читал в функции new можно указать размер выделяемой памяти, а можно просто написать new(P1). Тогда для P1 выделится стандартный размер...

Это я ошибся.

Что (и скока) ты хочешь получить после вызова
new(P1); // Выделяется память под PChar"ы


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

А как надо ?



 
Ihor Osov'yak   (2002-09-08 20:22) [5]

2 Aquaform.

Вот когда сообразиш ответ на вопросы ZZ и Anatoly Podgoretsky - может и понятно станет ...

Подсказка - new(P1) выделяет столько памяти, сколько занимает структура, тип которой соотв. типизированому указателю. то есть для pchar будет sizeof(char) ....

В делфи программе (имхо) без особой надобности pchar юзать не надо, даже если работаем с апи). Это относится к твоему случаю.

Ты мог работать с обычними string, примерно так:

var s:string;
x,y:integer;

..
s := "x="+IntToStr(x)+" y="+IntToStr(y);

messagebox(handle,PChar(s),"Координаты курсора",mb_ok);

SetLen(s,0); { это необязательно, так как для string в даном случае относится к автоуничтожаемым элементам}


ЗЫ - Если очень любозхнателен - почитай как делфи работает со строками...
Зы2 Юзай phar если понимаешь, что делаешь

Зы3 Чтение с для неокрепших умов очень вредно
Зы4 И трижды вреден необдуманный перенос сишного "експириенса" в делфи

..




 
Ihor Osov'yak   (2002-09-08 20:26) [6]

2 Aquaform.
Твой ответ на вропрос ZZ неверен. Но я очень надеюсь, что мой пред постинг тебе поможет разобратся. Разжевывание до конца в этом случае как то неприлично, ведь Вы все же на апи писать пытаетесь ...


 
Aquaform   (2002-09-08 23:51) [7]

Вот в чем дело. String я использовать не могу. Так как заменять
wvsprintf(P2,"%i",@x);
надо чем то вроде
S2:=inttostr(x);
что я себе позволить не могу, так как модуль SysUtils не подключен.

Далее. Я переделал New, Dispose на GetMem, FreeMem - таже ситуация (Run-time error):

if (msg=WM_LBUTTONUP) then
begin
GetMem(P1,255);
GetMem(P2,255);
GetMem(P3,255);
try
P1:="x=";
x:=loword(lpr);
y:=hiword(lpr);
wvsprintf(P2,"%d",@x);
P1:=lStrCat(P1,P2);
P1:=lStrCat(P1," y=");
wvsprintf(P3,"%i",@y);
P1:=lStrCat(P1,P3);
messagebox(handle,P1,"Координаты курсора",mb_ok);
finally
FreeMem(P1);
Freemem(P2);
FreeMem(P3);
end;
end;


 
Ihor Osov'yak   (2002-09-09 01:18) [8]

Мил человек, так подключи SysUtils. А если почему-то нет желания делать это, напиши что то типа

function IntToStr(aPrm:long):string;
var s:string;
begin
Str(aPrm,s);
result := s;
end;

и возврадуйся жизни ...

Далее:


GetMem(P1,255); - здесь все хорошо

P1:="x="; - а здесь мина. ибо поинтер смотрит уже не на запрошенную память, а на строку -константу длиной 2 байта

P1:=lStrCat(P1,P2); а злдесь возможен вылет, так как не известно что там у нас после двух байт константы

FreeMem(P1); - если перед тем не было вылета - то здесь точно - либо делаем попытку освободить память, которую не запрашивали -
напомина про P1:="x="; - сея вещь не копирует строку, а присвавает роинтеру P1 новое значение ...

... Я позволю себе быть не вежливым - мил человек, Вам не на апи программировать (во всяком случае пока), а книжки читать надо ...











 
Ihor Osov'yak   (2002-09-09 01:19) [9]

поправка

вместо либо делаем попытку
должно ибо делаем попытку


 
ggrisha   (2002-09-09 09:49) [10]

Ihor Osov"yak
нет там никакой мины
P1:="x="; не изменит указатель а запишет в выделенную область памяти значение.

Aquaform
Вообщето у меня этот пример с Getmem/Freemem на D6 вполне работает. Попробуй во Freemem непосредственно указать размер Freemem(P1,255); и т.д.


 
Aquaform   (2002-09-09 09:54) [11]

Ihor Osov"yak, спасибо огромное ! Вы единственный, кто мне все внятно расстолковал. А книжки я читал, только про PChar"ы доступно и объемно нигде не нашел. Везде все на VCL


 
ZZ   (2002-09-09 10:18) [12]

P1:="x="; не изменит указатель а запишет в выделенную область памяти значение
Да? Ты это сам проверял?


 
ggrisha   (2002-09-09 10:29) [13]

ZZ
конечно проверял.
Достаточно сравнить адрес указателя до присваивания и после. Они совпадают.


 
Ihor Osov'yak   (2002-09-09 10:34) [14]

2 ggrisha
А Вы уверены? Проверяли?

Подсказка: Сделайте просмотр pointer(P1) в режиме трассировки
до и после P1:="x="; ... А тогда и говорите.

2. Всякие шаманские действия (типа указывания 255) иногда и дают результат при одном - двум пробегам программы, хотя бы потому, что луна за вербу забежала... Но не надо делать скоропалительных выводов. Запустите фрагмент в цикле, так сотню раз ....

to Aquaform - согласен, довольно много книжек имеют уровень ... (нет, я лучше помолчу). Но в вашем случае достаточно было почитать внимательно хелп к GetMem и вспомнить, что PChar есть не более чем типизованый указатеть .... Согласен, в делфи вокруг
PChar много туману напущено, один из них - как PChar в режиме просмотра отображается (фактически мы пишем P1, а среда нам дает
к просмотру P1^ .... Поэтому и мой совет про pointer(P1)

ЗЫ - а Подгоретский и ZZ тебе тоже самое говорили, но как бы более концентрировано :-)


 
Ihor Osov'yak   (2002-09-09 10:40) [15]

2 ggrisha -

> конечно проверял.
> Достаточно сравнить адрес указателя до присваивания и после.
> Они совпадают


Ну до чего человек же упрям. Не адрес указхателя сравнивать, а значение ... См мой пред постинг
Или сделай ShowMessage(IntToHex(integer(P1),8));

И призадумайся, почему P1 к интеджер приводится


 
ZZ   (2002-09-09 12:02) [16]

ggrisha
procedure TForm1.Button1Click(Sender: TObject);
var
p : PChar;
begin
GetMem(p,255);
p:="f";
FreeMem(p);
end;

Запусти и проверь...



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2002.10.21;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.007 c
3-68616
Vagrant
2002-09-29 05:48
2002.10.21
Проблема с загрузкой и чтением отчета (FastReport) в/из BLOB


14-68914
iNew
2002-09-26 21:34
2002.10.21
Помогите новичку


4-69058
Alx2
2002-09-06 14:54
2002.10.21
Глючит RichEdit1.Perform(EM_CHARFROMPOS,0,0)


1-68776
sascha
2002-10-11 17:46
2002.10.21
формы


4-69051
Xemax
2002-09-04 19:36
2002.10.21
как полностью отключить Windows File Protection?





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