Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.08.2012, 19:24   #1
c0mp
 
Регистрация: 27.11.2011
Сообщений: 9
По умолчанию Как правильно выделить буфер для приёма строки от WinApi функции

Мне нужно получить заголовок окна, зная его хэндл. Я нашёл функцию:

Код:
int WINAPI GetWindowText(
  __in   HWND hWnd,
  __out  LPTSTR lpString,
  __in   int nMaxCount
);
Т.е lpString - это указатель на буфер, в который скопируется заголовок окна. Я решил, что сначала нужно определить длину заголовка, а потом зная длину выделить буфер (GetMem'ом). Вот эта функция:

Код:
int WINAPI GetWindowTextLength(
  __in  HWND hWnd
);
Но она возвращает длину заголовка окна в символах.
Цитата:
the return value is the length, in characters, of the text
А в GetMem, как я понимаю, нужно передавать размер в байтах.
Собственно вопрос, как правильно выделить память? (Точнее, как узнать сколько её нужно выделить). Если можно, приведите пожалуйста пример.
c0mp вне форума Ответить с цитированием
Старый 02.08.2012, 19:55   #2
Somebody
Участник клуба
 
Регистрация: 08.10.2007
Сообщений: 1,185
По умолчанию

Ну так прибавь 1 (под нулевой символ) и умножь на размер символа.
Somebody вне форума Ответить с цитированием
Старый 02.08.2012, 20:17   #3
c0mp
 
Регистрация: 27.11.2011
Сообщений: 9
По умолчанию

Так правильно?

Код:
function GetWindowCaption(Handle: HWND): String;
var
  buf: PChar;
  bufSize: Integer;
  WindowTextLength: Integer;
begin
  WindowTextLength := GetWindowTextLength(Handle);
  if GetLastError <> 0 then begin ShowMessage('Ошибка'); Exit; end;
  bufSize := (WindowTextLength * SizeOf(Char)) + 1;
  GetMem(buf, bufSize);
  try
    GetWindowText(Handle, buf, WindowTextLength + 1);
    if GetLastError <> 0 then begin ShowMessage('Ошибка'); Exit; end;
    Result := String(buf);
  finally
    FreeMem(buf, bufSize);
  end;
end;

Последний раз редактировалось c0mp; 02.08.2012 в 20:36. Причина: поправил код
c0mp вне форума Ответить с цитированием
Старый 02.08.2012, 20:51   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Код:
function GetWindowCaption(Handle: HWND): String;
begin
  SetLength(Result,GetWindowTextLength(Handle));
  SetLength(Result,GetWindowText(Handle,@Result[1],Length(Result));
end;
достаточно.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 02.08.2012, 21:01   #5
c0mp
 
Регистрация: 27.11.2011
Сообщений: 9
По умолчанию

Пепел Феникса, обрезается последний символ.
c0mp вне форума Ответить с цитированием
Старый 02.08.2012, 21:03   #6
c0mp
 
Регистрация: 27.11.2011
Сообщений: 9
По умолчанию

Может так:
Код:
function GetWindowCaption(Handle: HWND): String;
begin
  SetLength(Result,GetWindowTextLength(Handle)+1);
  SetLength(Result,GetWindowText(Handle,@Result[1],Length(Result)));
end;
?
c0mp вне форума Ответить с цитированием
Старый 02.08.2012, 21:10   #7
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Код:
function GetWindowCaption(Handle: HWND): String;
begin
  SetLength(Result,GetWindowTextLength(Handle));
  SetLength(Result,GetWindowText(Handle,@Result[1],Length(Result)+1));
end;
прошу прощения, вот так надо.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 02.08.2012, 21:52   #8
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Чуть корректнее будет так:
Код:
function GetWindowCaption(Handle: HWND): String;
begin
  SetLength(Result, GetWindowTextLength(Handle) + 1);
  SetLength(Result, GetWindowText(Handle, PChar(Result), Length(Result)));
end;
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 02.08.2012, 21:57   #9
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

GunSmoker, нет, Делфи строки хранятся как нуль терминированные, и нет нужды вносить терминал в саму строку.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 02.08.2012, 22:04   #10
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Так я и не говорил, что твой код не будет работать.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как правильно возвращать созданный в функции объект? rpy3uH Общие вопросы C/C++ 4 10.11.2011 16:19
Не знаю как правильно сделать вызов функции Homutova_Julia Помощь студентам 14 07.06.2011 23:45
Как правильно вставить строки? Kostinok Microsoft Office Excel 6 28.05.2010 19:23
скрипт для приёма заказов на печать фото, через Интернет nickhop Фриланс 1 14.02.2010 18:11
как правильно прописать адрес в функции? (формула) coldis Microsoft Office Excel 3 18.02.2009 09:47