IMHO.WS

IMHO.WS (https://www.imho.ws/index.php)
-   Программирование (https://www.imho.ws/forumdisplay.php?f=40)
-   -   Delphi+API (https://www.imho.ws/showthread.php?t=76318)

Zueuk 23.12.2004 17:06

Delphi+API
 
SendMessage(hEdit,EM_GETLINE, 0, chBuff);
// pBuff:=@chBuff;
// GetMem(pBuff,chBuff);
MessageBox(MainWnd, pBuff, 'Win Min', MB_OK);

Проблемка:
требуется из строки передать введенный текст и выдать в окно сообщения.
Примерчик выше.
Кто знает подскажите.

PS выдается пустота.

/7y3uK 23.12.2004 18:06

em_GetLine
Возвращает одну строку из органа управления редактированием.
Возвращается фактически переданное в буфер число байт, пустой символ завершения к концу буфера не добавляется. Это сообщение относится к многострочным органам управления редактированием.

em_GetHandle
Возвращает описатель буфера органа управления редактированием. Буфер содержит текст органа управления редактированиея. Не используются w и l параметры. Работает только для органа управления редактированием, созданного со стилем ds_LocalEdit.

Чето, либо я туплю либо еще что-то :) Но у меня не вышло привинтить указатель и получить текст, хотя ИМХО собака тут порылась в мессаге...
Как справишься - обязательно выложи код... тока с варами.

ЕЖ 23.12.2004 18:41

Ну не знаю, вот пишу на С++Builder, всё работает. На форме TEdit и TButton...

Код:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  char chBuff[1024];
  SendMessage(Edit1->Handle, EM_GETLINE, 0, (long)chBuff);
  MessageBox(Handle, chBuff, "Caption", MB_OK);
}


Zueuk 23.12.2004 21:41

ЕЖ мне нужно на Делфи именно. и на чистом API. насколько возможно.

Ниже текст самого кода. Он несет только ознакомительный характер. образец.

Код:

program winmin;

uses
  windows,
  messages;

{!Модули windows и messages  самые необходимые — они обязательно должны быть
объявлены в начале каждой Вашей программы!}

const
ID_EDIT=1001;
ID_BUTTON=1002;

var  wc : TWndClassEx;//Переменная шаблона класса окна
 MainWnd : HWND;      //Описатель главного окна
    Mesg : TMsg;      //Переменная для цикла сбора сообщений

    hStatic:HWND;
    hEdit:HWND;
    hButton:HWND;

//    Title:string='Win Min';

//    chBuff:integer;
    pBuff:pointer;
    chBuff:LPARAM;
//    chBuff:AnsiString;

{  Далее следует оконная процедура главного окна. Обратите внимание на служебное
  слово stdcall оно вынуждает компилятор генерировать особый вид кода, который
  может быть вызван любой windows-программой, без этого служебного слова
  программа не сможет  работать вообще!}
function WindowProc(MainWnd:HWND; Msg : Integer; Wparam:Wparam; Lparam:Lparam):Lresult;
 stdcall;

Begin
{Далее происходит цикл обработки сообщений}
case msg of
WM_CREATE:
  begin
  hStatic:=CreateWindow('static', 'Введите строку и нажмите кнопку OK',
    WS_CHILD or WS_VISIBLE or SS_CENTER, 30,10,300,20,MainWnd,0,hInstance,NIL);

  hEdit := CreateWindow('edit', NIL,
    WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT, 30, 40, 300, 30,
    MainWnd, ID_EDIT,hInstance,NIL);

  hButton := CreateWindow('button', 'OK',
    WS_CHILD or WS_VISIBLE or BS_PUSHBUTTON,130, 85,100, 30,
    MainWnd,ID_BUTTON,hInstance,NIL);

  SetFocus(hEdit);
  end;

WM_COMMAND:
  begin
  case (LOWORD(wParam)) of
  ID_EDIT:
    if ((HIWORD(wParam)) = EN_ERRSPACE)
    then MessageBox(MainWnd,'Мало памяти','Win Min',MB_OK);
  ID_BUTTON:
    begin
    SendMessage(hEdit,EM_GETLINE, 0, chBuff);
//    pBuff:=@chBuff;
//    GetMem(pBuff,chBuff);
    MessageBox(MainWnd, pBuff, 'Win Min', MB_OK);
    SetWindowText(hEdit,#10);//
    SetFocus(hEdit);
    end;
  end;
  end;

wm_destroy ://Сообщение посылаемое при уничтожении окна
  Begin
  postquitmessage(0); //exit;
  Result:=0;
  End;

  else Result:=DefWindowProc(MainWnd,msg,wparam,lparam);
end;

End;
{Переменные xPos,yPos,nWidth,nHeight в принципе не нужны, однако я их завел
(и вам рекомендую) для лучшей читабельности программы}
var xPos,yPos,nWidth,nHeight : Integer;

begin
{  Далее идет заполнение шаблона класса окна
  подробное описание полей этой записи см. после текста программы}
wc.cbSize:=sizeof(wc);
wc.style:=cs_hredraw or cs_vredraw;
wc.lpfnWndProc:=@WindowProc;
wc.cbClsExtra:=0;
wc.cbWndExtra:=0;
wc.hInstance:=HInstance;
wc.hIcon:=LoadIcon(0,idi_application);
wc.hCursor:=LoadCursor(0,idc_arrow);
wc.hbrBackground:=COLOR_BTNFACE+1;
wc.lpszMenuName:=nil;
wc.lpszClassName:='WinMin : Main';

RegisterClassEx(wc);//Регистрация нового класса в системе
{  Заполнение переменных xPos,yPos,nWidth,nHeight}
xPos:=200;
yPos:=150;
nWidth:=600;
nHeight:=400;

{  Создание главного окна}
MainWnd:=CreateWindowEx(
0,                  //флаги расширенных стилей
'WinMin : Main',    //имя класса окна, данное при заполнении структуры wc
'Win Min',          //заголовок окна
ws_overlappedwindow,//флаги стилей окна
xPos,              //горизонтальная позиция окна
yPos,              //вертикальная позиция окна
nWidth,            //ширина окна
nHeight,            //высота окна
0,                  //описатель родительского окна (parent) или окна-владельца (owner)
0,                  //описатель меню окна (меню нет, нет и описателя)
Hinstance,          //описатель приложения
nil                //address of window-creation data
);

ShowWindow(MainWnd,SW_SHOW);//Отображаем окно

//Цикл обработки сообщений
//он может слегка видоизменяться, но эти строчки присутсвуют всегда
While GetMessage(Mesg,0,0,0) do
 begin
  TranslateMessage(Mesg);
  DispatchMessage(Mesg);
 end;

end.


ЕЖ 23.12.2004 23:07

Цитата:

Zueuk:
ID_BUTTON:
begin
SendMessage(hEdit,EM_GETLINE, 0, chBuff);
// pBuff:=@chBuff;
// GetMem(pBuff,chBuff);
MessageBox(MainWnd, pBuff, 'Win Min', MB_OK);
Я что-то не пойму где ты выделяешь память под chBuff перед вызовом SendMessage? За тебя её никто выделять не будет, ты должен передавать уже заготовленный буфер. И если у тебя LPARAM chBuff является указателем на получаемую null-terminated строку, то почему ты в закомментареном коде пытаешься брать адрес указателя и присваивать его другому указателю (pBuff:=@chBuff)? Тут нужно лишь преобразование типа указателя. После всего этого совершенно не понятно как у тебя вообще выдается пустое значение. Посмотри в отладчике что содержится в памяти (побайтно) по адресу chBuff после вызова SendMessage.

Zueuk 24.12.2004 17:32

ЕЖ
Цитата:

ЕЖ:
почему ты в закомментареном коде пытаешься брать адрес указателя и присваивать его другому указателю (pBuff:=@chBuff)
Если бы я понимал разницу между указателем и адресом указателя, я бы написал что-то отличное от pBuff:=@chBuff.

Цитата:

ЕЖ:
Тут нужно лишь преобразование типа указателя.
Я знаю только функции преобразования, к примеру, из интеджера в стринг. Это просто. Функций же преобразования типов указателя я не встречал нигде. Еслиб увидел такую - использовал.

Цитата:

ЕЖ:
После всего этого совершенно не понятно как у тебя вообще выдается пустое значение.
Так исходник рабочий. Если у тебя есть или стоит делфи, ты можешь откомпилировать и посмотреть. Если не трудно, конечно.

Ты бы мог бы предложить вариант решения проблемки :)

В оригинале на си было так:
SendMessage( hEdit,EM_GETLINE, 0, (LPARAM)chBuff);
MessageBox(hwnd, chBuff, szTitle, MB_OK);

(LPARAM)chBuff это вроде объявление переменной. Но во второй функции переменная chBuff должна быть строкового типа. Вот я и пытался решить эту загвоздку, как преобразовать в совместимые типы в одной функции и в другой.

ЕЖ 24.12.2004 18:48

Цитата:

Сообщение от Zueuk
Если бы я понимал разницу между указателем и адресом указателя, я бы написал что-то отличное от pBuff:=@chBuff.

Ну вот тебе на пальцах:
Указатель любого типа который ты пользуешь в Delphi - это обычная переменная размером 4 байта - можешь считать её типом integer. Любой адрес, представляемый указателем, это 4-х байтовое число. Это число и хранится в 4-х байтах переменной указателя. Сами эти байты 4 байта содержимого переменной-указателя тоже, естественно, находятся по какому то 4-х байтовому адресу в памяти.

В chBuff у тебя должен быть указатель на последовательный набор получаемых символов (т.е. байт). Т.е. в chBuff находится адрес первого из этих символов в памяти. Делая pBuff:=@chBuff ты получаешь в pBuff не адрес этого первого символа строки, а адрес переменной chBuff. Получается указатель на указатель. А тебе надо лишь чтобы в pBuff и в chBuff был один и тот же адрес. Разница лишь в том что т.к. chBuff указатель на char, то сhBuff^ интерпретируется байт, а pBuff^ будет интерпретироваться как 4 байта - это зависит от типа указателя при его объявлении. Тип Pointer - универсальный (в С - это void), т.е. может принимать значение указателя любого другого типа.

Попробуй так:
Код:

var
  chBuff: PChar;
...

  GetMem(chBuff, 1024);
  GetWindowText(hEdit, chBuff, 1024);
  MessageBox(hWnd, chBuff, "Caption", MB_OK);
  ...

  FreeMem(chBuff, 1024);


Zueuk 24.12.2004 19:26

Цитата:

ЕЖ:
Ну вот тебе на пальцах:
Спасибо! :) И за разъяснения.

Проблемка разрешилась следующим образом:

Цитата:

program winmin;

uses
windows,
messages;

{!Модули windows и messages самые необходимые — они обязательно должны быть
объявлены в начале каждой Вашей программы!}

const
ID_EDIT=1001;
ID_BUTTON=1002;

var wc : TWndClassEx;//Переменная шаблона класса окна
MainWnd : HWND; //Описатель главного окна
Mesg : TMsg; //Переменная для цикла сбора сообщений

hStatic:HWND;
hEdit:HWND;
hButton:HWND;

chBuff:widestring;

{ Далее следует оконная процедура главного окна. Обратите внимание на служебное
слово stdcall оно вынуждает компилятор генерировать особый вид кода, который
может быть вызван любой windows-программой, без этого служебного слова
программа не сможет работать вообще!}
function WindowProc(MainWnd:HWND; Msg : Integer; Wparam:Wparam; Lparam:Lparam):Lresult;
stdcall;

Begin
{Далее происходит цикл обработки сообщений}
case msg of
WM_CREATE:
begin
hStatic:=CreateWindow('static', 'Введите строку и нажмите кнопку OK',
WS_CHILD or WS_VISIBLE or SS_CENTER, 30,10,300,20,MainWnd,0,hInstance,NIL);

hEdit := CreateWindow('edit', NIL,
WS_CHILD or WS_VISIBLE or WS_BORDER or ES_LEFT, 30, 40, 300, 30,
MainWnd, ID_EDIT,hInstance,NIL);

hButton := CreateWindow('button', 'OK',
WS_CHILD or WS_VISIBLE or BS_PUSHBUTTON,130, 85,100, 30,
MainWnd,ID_BUTTON,hInstance,NIL);

SetFocus(hEdit);
end;

WM_COMMAND:
begin
case (LOWORD(wParam)) of
ID_EDIT:
if ((HIWORD(wParam)) = EN_ERRSPACE)
then MessageBox(MainWnd,'Мало памяти','Win Min',MB_OK);
ID_BUTTON:
begin
SendMessage(hEdit,WM_GETTEXT, 255, Integer(@chBuff));
MessageBox(MainWnd,@chBuff, 'Win Min', MB_OK);
SetWindowText(hEdit,#10);//
SetFocus(hEdit);
end;
end;
end;

wm_destroy ://Сообщение посылаемое при уничтожении окна
Begin
postquitmessage(0); //exit;
Result:=0;
End;

else Result:=DefWindowProc(MainWnd,msg,wparam,lparam);
end;

End;
{Переменные xPos,yPos,nWidth,nHeight в принципе не нужны, однако я их завел
(и вам рекомендую) для лучшей читабельности программы}
var xPos,yPos,nWidth,nHeight : Integer;

begin
{ Далее идет заполнение шаблона класса окна
подробное описание полей этой записи см. после текста программы}
wc.cbSize:=sizeof(wc);
wc.style:=cs_hredraw or cs_vredraw;
wc.lpfnWndProc:=@WindowProc;
wc.cbClsExtra:=0;
wc.cbWndExtra:=0;
wc.hInstance:=HInstance;
wc.hIcon:=LoadIcon(0,idi_application);
wc.hCursor:=LoadCursor(0,idc_arrow);
wc.hbrBackground:=COLOR_BTNFACE+1;
wc.lpszMenuName:=nil;
wc.lpszClassName:='WinMin : Main';

RegisterClassEx(wc);//Регистрация нового класса в системе
{ Заполнение переменных xPos,yPos,nWidth,nHeight}
xPos:=200;
yPos:=150;
nWidth:=600;
nHeight:=400;

{ Создание главного окна}
MainWnd:=CreateWindowEx(
0, //флаги расширенных стилей
'WinMin : Main', //имя класса окна, данное при заполнении структуры wc
'Win Min', //заголовок окна
ws_overlappedwindow,//флаги стилей окна
xPos, //горизонтальная позиция окна
yPos, //вертикальная позиция окна
nWidth, //ширина окна
nHeight, //высота окна
0, //описатель родительского окна (parent) или окна-владельца (owner)
0, //описатель меню окна (меню нет, нет и описателя)
Hinstance, //описатель приложения
nil //address of window-creation data
);

ShowWindow(MainWnd,SW_SHOW);//Отображаем окно

//Цикл обработки сообщений
//он может слегка видоизменяться, но эти строчки присутсвуют всегда
While GetMessage(Mesg,0,0,0) do
begin
TranslateMessage(Mesg);
DispatchMessage(Mesg);
end;

end.
Нашлась функция приведения Integer(@chBuff)
SendMessage(hEdit,WM_GETTEXT, 255, Integer(@chBuff));
Так же взял параметр WM_GETTEXT. Так нормально работает. И добавляется 255 (количество извлекаемых символов, как я понял). Т.е. если пишешь 5 извлечется 4, на единицу меньше.

И резервирование памяти не потребовалось.


Часовой пояс GMT +4, время: 22:16.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.