FAQ:WinAPI, VCPP Part 3
Содержание
- 1 Имеется приложение на основе CRichEditView. Как узнать, что пользователь меняет текст?
- 2 Чем метод CArray::GetSize отличается от метода CArray::GetCount?
- 3 Как загрузить строку из ресурса?
- 4 Как поменять иконку у элемента (item) в CListCtrl ?
- 5 Имеется класс Class1, содержащий мембер типа указатель на Class2. В Class2 также имеется указатель на Class1. Компилятор выдаёт ошибку. Что надо делать?
- 6 Как переключить раскладку в другом (то есть в активном) процессе?
- 7 Как получить хендл контрола Edit зная его ID ?
- 8 Как из дочернего окна закрыть приложение?
- 9 Как корректно перевести BSTR в CString и наоборот?
- 10 Как получить доступ к графическим ресурсам элементов текущей темы оформления Windows?
- 11 Имеется класс , производный от CDialog. Когда диалог в фокусе, нажатие на Enter или Esc приводит к закрытию диалога. Как это запретить?
- 12 VC++6. Я написал простейший макрос, а компилятор на него ругается. ума не приложу, что за глюк?
- 13 Как получить список всех процесов, включая idle ?
- 14 Как программно установить переменные окружения?
- 15 Как сделать,чтобы у окна был черный фон?
- 16 Почему на моем компьютере экзешник, созданный в MFC запускается, а на других компьютерах - нет? Требует какую-то dll-ку.
- 17 Как в диалог добавить меню?
- 18 Я добавил визардом меню в диалог. Добавил обработчики для пунктов меню. Но пункты работают, но OnUpdate для пунктов не вызывается - то есть не получается ни затенить, ни чек поставить. Что делать?
Имеется приложение на основе CRichEditView. Как узнать, что пользователь меняет текст?
Добавить обработчик сообщения EN_CHANGE. Сообщение генерируется CRichEditView каждый раз, когда пользователь изменяет текст в окне CRichEditView
Чем метод CArray::GetSize отличается от метода CArray::GetCount?
Абсолютно ничем. (Скорее всего, были предыдущие библиотеки, в которых функции, одинаковые по смыслу, имели разные имена. Поэтому в целях совместимости оставили оба)
Как загрузить строку из ресурса?
CString m_Temp; m_Temp.LoadString(ID_MYSTRING);
Как поменять иконку у элемента (item) в CListCtrl ?
//заполняем структуру LVITEM LVITEM lvItem; memset(&lvItem,0,sizeof(lvItem)); lvItem.mask = LVIF_IMAGE;//меняться будет картинка lvItem.iItem = ...;// индекс элемента списка (Zero-based) lvItem.iSubItem = 0; lvItem.iImage = ...; //индекс иконки (из списка контрола) pList->SetItem(& lvItem);
Имеется класс Class1, содержащий мембер типа указатель на Class2. В Class2 также имеется указатель на Class1. Компилятор выдаёт ошибку. Что надо делать?
Предварительно объявляем класс Class2. Тогда компилятору будет известно, что описание класса Class2 будет встречено дальше, и станет возможным объявление указателей на класс до описания самого класса.
Class2;//предопределение Class1 { Class2* p; }; Class2 { Class1* p; };
Как переключить раскладку в другом (то есть в активном) процессе?
Использовать функции:
GetKeyboardLayout - определить текущую раскладку LoadKeyboardLayout - загрузить новую раскладку
см.также
VerLanguageName - получить строку с описанием языка
(подробности - в MSDN)
Как получить хендл контрола Edit зная его ID ?
Пусть контрол лежит на окне CMyWnd Тогда:
void CMyWnd::некая_процедура() { //для MFC CEdit* ed=(CEdit* ) GetDlgItem(ID_EDIT1); HWND hwnd=ed->GetSafeHwnd(); ... //для Win32 API HWND hwnd=GetDlgItem(m_hWnd,ID_EDIT1); ... }
Как из дочернего окна закрыть приложение?
Нужно послать родительскому окну (*pParent) сообщение WM_CLOSE:
pParent->PostMessage(WM_CLOSE);//MFC
или
::PostMessage(pParent->m_hWnd,WM_CLOSE,(WPARAM)0,(LPARAM)0);//API
Как корректно перевести BSTR в CString и наоборот?
1) Нужно просто присвоить переменной типа CString переменную типа BSTR. Оператор = класса CString сам всё переведёт.
2)
//указатель на будущий буфер с BSTR. // (По сути, BSTR определён как // typedef WCHAR* BSTR; // то есть указатель на 16-битный символ юникод) BSTR bstrHE=0; CString Str="мой текст"; //Выделить память и загрузить адрес блока в bstrHE bstrHE=Str.AllocSysString(); //... //тут работаем с bstrHE[] //... //освобождаем память SysFreeString(bstrHE);
Как получить доступ к графическим ресурсам элементов текущей темы оформления Windows?
Использовать функции
OpenThemeData() DrawThemeBackground() DrawFrameControl() CloseThemeData().
(подробности - в MSDN)
Имеется класс , производный от CDialog. Когда диалог в фокусе, нажатие на Enter или Esc приводит к закрытию диалога. Как это запретить?
При нажатии Enter происходит выполнение команды IDOK, при нажатии Esc - IDCANCEL. Нужно переопределить в классе виртуальные функции OnOk() и OnCancel(), которые соответственно вызываются для этих команд. При помощи визарда эти функции добавить можно так: Положить на диалог две кнопки с идентификаторами IDOK и IDCANCEL (при создании нового диалога они там есть сразу), затем двойной клик по кнопке добавляет соответствующий обработчик. В обработчиках надо удалить вызовы СDialog::OnOK() и CDialog::OnCancel(), тогда диалог закрываться не будет. Однако тогда диалог станет невозможно закрыть кнопкой с крестиком :)
Лечить так: добавить обработчик сообщения WM_CLOSE - OnClose(), и в нём сделать вызов OnOk() или OnCancel() :
void CPlayersPropsDialog::OnClose() { CDialog::OnClose(); CDialog::OnCancel();//добавлено }
VC++6. Я написал простейший макрос, а компилятор на него ругается. ума не приложу, что за глюк?
#define my_macr(x,y,z) \ z=\ (x+y)*\ (x-y)
Скорее всего после одного из символов соединения строк "\" имеется пробел или табуляция. Их надо удалить. Можно найти их "наощупь", а можно включить показ непечатных символов в студии. Найти эту команду можно так: Tools->Customize...->вкладка Commands. , В окошке Category выбрать "Edit", и среди кнопок справа найти кнопку , на которой написано "a.b" Эту кнопку надо перетащить на одну из панелей инструментов студии.
Как получить список всех процесов, включая idle ?
Использовать функции Process32First() Precess32Next()
Как программно установить переменные окружения?
Чтобы добавить или изменить их программно, необходимо воспользоваться ключом реестра HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\ Session Manager\Environment, а затем отправить широковещательное сообщение WM_SETTINGCHANGE. Это позволит приложениям узнать об изменениях:
- SendMessage(HWND_BROADCAST,WM_SETTINGCHANGE,0,0);
Как сделать,чтобы у окна был черный фон?
переопределить обработчик сообщения WM_CTLCOLOR - OnCtlColor() :
CBrush br(RGB(0,0,0)); HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { HBRUSH hbr = CMyDlg::OnCtlColor(pDC, pWnd, nCtlColor); //фон диалога (или вьюшки) if(nCtlColor==CTLCOLOR_DLG) { return (HBRUSH)br; } //фон статиков (если нужно) if(nCtlColor==CTLCOLOR_STATIC) { //делаем фон текста статика прозрачным pDC->SetBkMode(TRANSPARENT); return (HBRUSH)br; } return hbr; }
Почему на моем компьютере экзешник, созданный в MFC запускается, а на других компьютерах - нет? Требует какую-то dll-ку.
Нужно выбирать режим Release :
Menu->Build->Configurations...->Release,
и экзешник, соответственно, брать из папки Release проекта
Как в диалог добавить меню?
Надо сделать в ресурсах меню, затем вставить в диалог:
открыть в редакторе диалог, в свойствах (во вкладке General, окошко Menu) указать идентивикатор ресурса меню. При помощи визарда добавить для меню обработчики OnCommand() и OnUpdateСommand().
Я добавил визардом меню в диалог. Добавил обработчики для пунктов меню. Но пункты работают, но OnUpdate для пунктов не вызывается - то есть не получается ни затенить, ни чек поставить. Что делать?
В диалоге у меню апдейта не происходит сам, в отличие от мейнфрейма. Для этого нужно сделать самим апдейт в обработчике сообщения WM_KICKIDLE. Визардом обработчик не добавляется, поэтому можно переопределить виртуальную DefWindowProc() и там обработать:
#include <afxpriv.h> //этот файл надо включить, там определёна WM_KICKIDLE