Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» C++ WinAPI

Автор: Abs62
Дата сообщения: 13.10.2009 07:49
peacedeth
И надо ещё не забыть, что с кнопками можно и с клавиатуры работать, а не только мышкой.
Автор: ShIvADeSt
Дата сообщения: 13.10.2009 07:59
Qraizer

Цитата:
Мда... Более вредного совета на примете нет?

Если необходимо моментально прервать работу потока, то я другого способа не знаю. Но я не силен в разработке многопоточных приложений, если есть идея получше - то поделитесь
Abs62

Цитата:
И надо ещё не забыть, что с кнопками можно и с клавиатуры работать, а не только мышкой.

Согласен, надо добавить по хорошему WM_CHAR и WM_KEYDOWN (хотя у чара только на момент отпускания срабатывает).
Автор: peacedeth
Дата сообщения: 13.10.2009 17:04
Невероятно но факт!
Сделал проект, с вкладками и кнопкой. Создал сабкласс для кнопки, ловлю WM_LBUTTONDOWN на кнопке, увожу курсор с кнопки, отжимаю клавишу мыши, и сабкласс кнопки ловит WM_LBUTTONUP! И это вне зависимости в какой части экрана я отпустил кнопку мыши.
Автор: peacedeth
Дата сообщения: 13.10.2009 23:39
Решил сделать управление с клавиатуры, но никак не могу поймать сообщение о нажатии клавиш. Сообщения WM_KEYDOWN не приходят не в одну процедуру-обработчик (ни в оконную, ни в процедуру диалога). Ловится только процедурой обработаки сообщений кнопки (которую сделал сабклассингом) когда фокус стоит на какой нибудь из кнопок.

У меня в окне несколько вкладок. Каждая вкладка диалог имеющий свою процедуру. Как ловить сообщения о нажатии клавишь в каждой вкладке по отдельности?
Автор: Abs62
Дата сообщения: 14.10.2009 00:15
peacedeth

Цитата:
Каждая вкладка диалог имеющий свою процедуру. Как ловить сообщения о нажатии клавишь в каждой вкладке по отдельности?

Диалог модальный или немодальный?
Если модальный - делать ему сабклассинг. Если немодальный - ловить в цикле опроса очереди сообщений до вызова IsDialogMessage.
А зачем такие сложности?
Автор: peacedeth
Дата сообщения: 14.10.2009 01:26
Abs62

Немодальный. А почему я нигде не могу поймать нажатие клавиши, даже в оконной процедуре?
Автор: Qraizer
Дата сообщения: 14.10.2009 02:49
ShIvADeSt

Цитата:
Если необходимо моментально прервать работу потока, то я другого способа не знаю.
Моментально необязательно. Человеческие пальцы не будут работать с той точностью, чтобы десятки или сотни миллисекунд играли роль. Немоментальные - это не прибить поток, а попросить его завершиться. Решений куча, от банального volatile флага, периодического опроса объектов синхронизации (ИМХО лучший выбор в подавляющем большинстве случаев), приостановка потока с последующим возобновлением вместо разрушения с дальнейшим созданием нового, итп.
TerminateThread() плохо хотя бы тем, что после ~2000 запусков-прибитий, а скорее даже раньше, у процесса кончится виртуальная память (а у винды - возможно, свап, а если и не кончится, то раздуется, правда, не на 2Гб, поменьше). Плюс поток за собой ничего не чистит, даже деструкторы объектов на стеке не отработают. И весь этот мусор остаётся с процессом, пока он сам весь не кончится.
Автор: ShIvADeSt
Дата сообщения: 14.10.2009 04:28
Qraizer
Согласен со всем этим, но так как от вопрошающего так и не увидел надо моментально или нет, то предложил этот вариант.
Будет уточнение - будет конкретизация.
Автор: Abs62
Дата сообщения: 14.10.2009 09:01
peacedeth
WM_KEYDOWN диспетчеризуется в IsDialogMessage по логике работы диалога. Потому надо ловить его до того.
Автор: peacedeth
Дата сообщения: 14.10.2009 12:28
ShIvADeSt
Моментальности не надо. Все равно в ходе выполнения будет делаться куча проверок, а так как на "другом конце" висит микроконтроллер и общение происходит коммандами, то тем более с моментальностью проблем нет. Главное что бы время отклика не превышало время такта COM порта.

Abs62
А можно по подробней про IsDialogMessage? Что то я в МСДН ничего конкретного не увидел.
Автор: Abs62
Дата сообщения: 14.10.2009 16:30
peacedeth
Дык, а что поподробнее? Стандартный цикл обработки сообщений для программы с немодальным диалогом выглядит примерно так:

Код: while(GetMessage(&msg,NULL,0,0)) {
if(hDlg==0 || !IsDialogMessage(hDlg,&msg)) { //hDlg - хэндл немодального диалога
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
}
Автор: akaGM
Дата сообщения: 21.10.2009 14:37
есть "залипший" файл (т.е. файл, кот. не удаляется никакими способами)
в принципе задача решается всякими unlocker'ами, но у меня вопрос:

возможно ли это сделать самому средствами апи? как?
Автор: Abs62
Дата сообщения: 21.10.2009 21:39
akaGM
Глянь здесь.
Автор: akaGM
Дата сообщения: 22.10.2009 13:05
Abs62
да...
на халяву не получится
спасибо за ссылку
Автор: V0lt
Дата сообщения: 20.01.2010 05:52
Задачка.
Допустим есть некий my.dll зарегистрированная командой Regsvr32 my.dll
Вопрос: Как сторонней утилите узнать, что данный файл действительно зарегистрирован в системе и если зарегистрирован, то как узнать путь к этому файлу?
Автор: Abs62
Дата сообщения: 20.01.2010 08:31
V0lt
Наверно, найти соответствующий GUID в HKEY_CLASSES_ROOT\CLSID и глянуть ключ InprocServer32.
Автор: V0lt
Дата сообщения: 20.01.2010 16:22
Abs62

Цитата:
Наверно, найти соответствующий GUID в HKEY_CLASSES_ROOT\CLSID и глянуть ключ InprocServer32

а я надеялся, что существует специальная функция
Автор: kok80
Дата сообщения: 21.01.2010 17:34
Помогите, или может у кого какие мысли рождаются:
запускаю внешнюю прогу, вызываю диалог открытия файла, нахожу хэндл EDIT, пытаюсь в него занести нужный пусть с имменем файла (delphi, но суть надеюсь понятна):

repeat WINDOW:=FindWindow('#32770','Открыть изображение'); until WINDOW>0;
repeat window:=FindWindowEx(window,0,'Edit',nil); until WINDOW>0;
window = хэндл EDIT в диалоговом окне

SendMessage(WINDOW,WM_SETTEXT,0,dword(comment))
результат a=1, те сообщение отправлено

a:=SendMessage(WINDOW,wm_gettextlength,0,0);
результат = длина отправленной строки

SendMessage(WINDOW,wm_gettext,100,dword(bufer));
в итоге bufer содержит строку, которую отправлял

Но зрительно я этой строки не вижу в EDIT, из другой програмы пытаюсь получить длину строки и строку - результат нулевой, те строка пуста
ставлю задержку SLEEP(1000) после findwindowex и перед wm_settext - все ок.

Вопросы -
1) что делаю не так?
2) как узнать при создании окна в чужой проге, что окно готово к работе
(с другими внешними приложениями - наличие хэндла окна через FindWindow было достаточным условием для манипуляций с окном, те есть хэндл - значит готово, а здесь ни фига)
3) чего этот гад врет, что EDIT содержит нужную строку нужной длины
Автор: Abs62
Дата сообщения: 21.01.2010 18:13
kok80

Цитата:
1) что делаю не так?


Цитата:
repeat window:=FindWindowEx(window,0,'Edit',nil); until WINDOW>0;

Если FindWindowEx вернула NULL, всё пойдёт наперекосяк.

Цитата:
3) чего этот гад врет, что EDIT содержит нужную строку нужной длины

Кто сказал, что врёт? Если та программа сама выставляет содержимое окна уже после того, как отработали WM_SETTEXT и WM_GETTEXT, так оно и получится. А судя по "ставлю задержку SLEEP(1000) после findwindowex и перед wm_settext - все ок" - так оно и есть.

Цитата:
2) как узнать при создании окна в чужой проге, что окно готово к работе

Ну, можно ещё попробовать подождать, пока оно будет показано. Через IsWindowVisible.
Автор: ShIvADeSt
Дата сообщения: 22.01.2010 01:47
ИМХО траблы в том, что окно помимо того, что получило текст должно еще перерисоваться, чтобы текст отобразить.
Автор: kok80
Дата сообщения: 22.01.2010 14:50

Цитата:
Цитата:repeat window:=FindWindowEx(window,0,'Edit',nil); until WINDOW>0;


Если FindWindowEx вернула NULL, всё пойдёт наперекосяк.


не, код как раз и ищет окно до тех пор, пока переменная WINDOW станет больше 0. Прекрасно везде и всегда находит все создающиеся окна.

А мысль о том, что после создания прога может обнулять строку мне в голову не пришла, и действительно IsWindowVisible спас ситуацию:

вместо SLEEP(1000) поставил repeat until IsWindowVisible(WINDOW) и всё заработало. Спасибо.
Автор: Abs62
Дата сообщения: 22.01.2010 16:06
kok80

Цитата:
не, код как раз и ищет окно до тех пор, пока переменная WINDOW станет больше 0.

Всё бы хорошо, но эта же переменная и задаёт родительское окно, в котором идёт поиск. Так что как только FindWindowEx вернёт NULL, следующий поиск уже пойдёт на Desktop, а не в найденном ранее окне.
Автор: VadimLou
Дата сообщения: 28.01.2010 04:45
V0lt

Цитата:
файл действительно зарегистрирован

ole32.dll -> if (Succeeded(StringFromCLSID(...
Автор: CruelCrow
Дата сообщения: 18.02.2010 14:06
Возможно ли модифицировать ресурс в памяти?
Т.е. у меня, к примеру, есть зашифрованный файл dialog.html, который присоединяется ресурсом к проекту.
Этот файл содержит текст "<lmth><ydob>12345</ydob></lmht>", а я хочу, чтобы после запуска программы запускался "дешифратор" и любое последующие обращение к ресурсу (в данном случае - отображение диалогового окна html) возвращало "<html><body>23456</body></html>".


Добавлено:
Всё, разобрался.


Код:
//modify html resource
//
HRSRC hRes;
HGLOBAL hResourceLoaded;
TCHAR *lpResLock = L" ";
DWORD dwSizeRes;

hRes = FindResource(NULL, MAKEINTRESOURCE(IDR_HTML_TEST_HTML_CIPHER_DIALOG), RT_HTML);
hResourceLoaded = LoadResource(NULL, hRes);
lpResLock = (TCHAR*) LockResource(hResourceLoaded);
dwSizeRes = SizeofResource(NULL, hRes);

int i;
for (i=0; i<=dwSizeRes-1; i++) lpResLock[i] = L'a';
//
Автор: koderr
Дата сообщения: 22.02.2010 17:08
Добрый день.
Проблема, собственно: есть Gdiplus::Graphics, созданный на основе записывающегося Gdiplus::Metafile, в этот Graphics отрисовываются по DrawImage другие метафайлы, т.е. несколько изображений объединяются в одно. Если памяти не хватает, то в один прекрасный момент DrawImage возвращает Win32Error и в итоге в файл ничего не записывается. Можно ли как-то "спасти" то, что уже отрисовалось?
Автор: alamar5
Дата сообщения: 02.03.2010 17:17
Привет всем!
Пытаюсь разобраться с таким вопросом.
В Windows кнопки в заголовке окна (Minimize/Restore, Maximize, Close) в зависимости от темы могут иметь разный размер и по-разному располагаться на заголовке.
Мне эти кнопки надо отрисовывать вручную вызовами DrawThemeBackground() и здесь нужны именно координаты прямоугольника.

У системы как-то можно узнать, в каком прямоугольнике должна рисоваться каждая кнопка?

Меня, главным образом, интересует способ, не базирующийся на каких-то предварительных "экспериментальных" измерениях зазоров между кнопками и т.п.
Автор: RedPromo
Дата сообщения: 02.03.2010 21:52
alamar5
int WINAPI GetSystemMetrics(
__in int nIndex
);
SM_CXSIZE 30    - The width of a button in a window caption or title bar, in pixels.
SM_CYSIZE 31    - The height of a button in a window caption or title bar, in pixels.
Автор: alamar5
Дата сообщения: 03.03.2010 00:55
RedPromo
Это всё понятно, но задача же не ограничивается нахождением размеров кнопок.
Прямоугольник кнопки надо еще расположить там, где надо.
Я понимаю, что можно путем подгона отрисовать кнопки там, где их рисует система, но это не то, что хотелось бы получить.
Собственно, для меня вопрос сводится к тому, как у системы именно расположение кнопок узнать.
Автор: ShIvADeSt
Дата сообщения: 03.03.2010 09:53
alamar5
Не узнаешь, сам бился с этой темой. Вернее мне не удалось.
Автор: RedPromo
Дата сообщения: 03.03.2010 11:30
alamar5
[more=Кусок кода DrawButtons]

Код:
////////////////
// Draw min, max/restore, close buttons.
// Returns total width of buttons drawn.
//
int CCaptionPainter::DrawButtons(const PAINTCAP& pc)
{
ASSERT(m_pWndHooked);
CWnd& wnd = *m_pWndHooked;
DWORD dwStyle = wnd.GetStyle();
if (!(dwStyle & WS_CAPTION))
return 0;

ASSERT(pc.m_pDC);
CDC& dc = *pc.m_pDC;


int cxIcon = GetSystemMetrics(SM_CXSIZE);
int cyIcon = GetSystemMetrics(SM_CYSIZE);


// Draw caption buttons. These are all drawn inside a
rectangle
// of dimensions SM_CXSIZE by SM_CYSIZE
CRect rc(0, 0, cxIcon, cyIcon);
rc += CPoint(pc.m_szCaption.cx-cxIcon, 0); // move right


// Close box has a 2 pixel border on all sides but left, which
is
zero
rc.DeflateRect(0,2);
rc.right -= 2;
dc.DrawFrameControl(&rc, DFC_CAPTION, DFCS_CAPTIONCLOSE);


// Max/restore button is like close box; just shift rectangle
left
// Also does help button, if any.
BOOL bMaxBox = dwStyle & WS_MAXIMIZEBOX;
if (bMaxBox || (wnd.GetExStyle() & WS_EX_CONTEXTHELP)) {
rc -= CPoint(cxIcon, 0);
dc.DrawFrameControl(&rc, DFC_CAPTION,
bMaxBox ? (wnd.IsZoomed() ?
DFCS_CAPTIONRESTORE :
DFCS_CAPTIONMAX) :
DFCS_CAPTIONHELP);
}

Страницы: 12345678910111213141516171819202122232425262728293031323334353637

Предыдущая тема: посоветуйте книги по SQL


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.