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

» C++ WinAPI

Автор: V0lt
Дата сообщения: 25.10.2011 18:53

Цитата:
bInitialOwner если True, то мутекс захватывается создавшим его потоком сразу после создания. До тех пор пока не будет вызван ReleaseMutex.

Мне непонятен термин "захватывается".


Цитата:
bInheritHandle стандартный апишный флаг, разрешающий наследовать хендлы в дочерних процессах.

Что значит "наследовать"? Мутекс же один.
У меня куча процессов, которые запускаются из проводника. Первый будет создавать мутекс, остальные будут его проверять через OpenMutex. В данном случае, есть смысл в параметре bInheritHandle или нет?
Автор: Abs62
Дата сообщения: 25.10.2011 19:46
V0lt

Цитата:
Мне непонятен термин "захватывается".

Почитай про принципы синхронизации в Win.

Цитата:
Первый будет создавать мутекс, остальные будут его проверять через OpenMutex.

Достаточно CreateMutex и проверить код возврата GetLastError. Если получил ERROR_ALREADY_EXISTS или ERROR_ACCESS_DENIED - значит, мьютекс уже был создан.

Цитата:
В данном случае, есть смысл в параметре bInheritHandle или нет?

Нет.
Автор: wasilissk
Дата сообщения: 25.10.2011 19:55
V0lt

Цитата:
Мне непонятен термин "захватывается".

Abs62 опередил, еще прикольное описание у Рихтера, через туалет на самолете.

Цитата:
Что значит "наследовать"? Мутекс же один.

Наследовать хендл мутекса. Обычно хендл валиден в рамках одного процесса, если установить bInheritHandle в True, то его можно будет использовать в дочерних процессах.

Цитата:
В данном случае, есть смысл в параметре bInheritHandle или нет?

В случае именованного мутекса нет, в случае неименованного - имеет.
Автор: V0lt
Дата сообщения: 25.10.2011 20:15

Цитата:
Достаточно CreateMutex и проверить код возврата GetLastError. Если получил ERROR_ALREADY_EXISTS или ERROR_ACCESS_DENIED - значит, мьютекс уже был создан.

Когда я использую CreateMutex, то поиск в ProcessExplorer выдает количество результатов равное количеству процессов. Если для первого процесса сделать CreateMutex, а для остальных OpenMutex, то ProcessExplorer выдаст только один результат.

Где-то читал, что CreateMutex пытается сначала открыть мутекс, и если потерпит неудачу, тогда создаст его. Т.е. если мутекс уже существует, то CreateMutex = OpenMutex, но на практике совсем не так.

Как бы получается, что OpenMutex ничего не открывает, а всего лишь проверяет наличие (есть или нет можно узнать через GetLastError). Оно конечно хорошо (мне как раз нужна функция, которая будет лишь проверять наличие мутекса), но ведь хрень какая-то получается.

PS: экспериментирую с ATL::CMutex

Добавлено:
Вот кусок кода (не Я придумал )

Код: ATL::CMutex m_mutexOneInstance;
...
m_mutexOneInstance.Create(NULL, TRUE, MPC_WND_CLASS_NAME);
if (GetLastError() == ERROR_ALREADY_EXISTS && ...) {
...
}
Автор: Sota
Дата сообщения: 25.10.2011 21:03
V0lt
Если english не пугает то можно сделать так:
http://bcbjournal.org/articles/vol3/9911/Single-instance_applications.htm

Таки мьютекс нужен, ибо в Win32 в WinMain самый нужный параметр hPrevInstance равен NULL.

В итоге имеем:
1. Пробуем создать мьтекс.
2. Если создалося, то мы самая первая инстанс приложения, запускаемся и работаем (мьютекс держим до завершения).
3. Если нет, то ищем окно (в примере как раз окно)
3.1 И если найдем, то скидываем ему файл для обработки.
3.2 И заканчиваем.
4. Мы первый инстанс, обработаем все что нам накидали.

Другой вопрос что будет когда не найдем окна?

Нут тут можно поспать миллисекунд 1000 и еще раз поискать попробовать.
Автор: Abs62
Дата сообщения: 25.10.2011 22:10
V0lt

Цитата:
Вот кусок кода (не Я придумал )

Так может дело не в мьютексе, а в том, что после идёт?
Кстати, там тоже этот мьютекс пригодиться может. Например, можно захватывать его при создании, а освобождать после создания главного окна (в обработчике WM_CREATE, скажем). А когда GetLastError вернёт ERROR_ALREADY_EXISTS, ждать освобождения через WaitForSingleObject и только после этого начинать искать окно. Тогда не будет этой угадайки - то ли окна ещё нет, то ли его уже нет.

Кстати, мне кажется, что лучше вынести CreateMutex к самому началу программы. Идеально, чтобы это вообще было первым её действием. Тогда от момента запуска до момента создания окна мьютекс будет занят.
Автор: V0lt
Дата сообщения: 26.10.2011 05:49
Sota
Очень хорошая статья, спасибо.

Abs62

Цитата:
Кстати, там тоже этот мьютекс пригодиться может. Например, можно захватывать его при создании, а освобождать после создания главного окна (в обработчике WM_CREATE, скажем).

Захватить/освободить - это Attach/Detach? А как потом проверить, что мютекс есть или его нет, и если есть, то он захвачен или освобожден?
Автор: wasilissk
Дата сообщения: 26.10.2011 06:48
V0lt

Цитата:
Захватить/освободить - это Attach/Detach?

WaitForSingleObject например или опять же параметр bInitialOwner. Вы статью прочитали на которую Abs62 ссылку давал? Что там может не получиться не понятно. Может стоит сначала на чистом API попробовать, прежде чем ATL использовать?
Автор: Abs62
Дата сообщения: 26.10.2011 08:21
V0lt
Первоначально захватить через bInitialOwner, освободить в обработчике WM_CREATE. А во втором экземпляре ждать освобождения.

Код: m_mutexOneInstance.Create(NULL, TRUE, MPC_WND_CLASS_NAME);
if (GetLastError() == ERROR_ALREADY_EXISTS) {
DWORD res=WaitForSingleObject(m_mutexOneInstance.HANDLE(),10000); //Таймаут лучше выставить с запасом
if(res==WAIT_OBJECT_0 || res==WAIT_ABANDONED) {
//Тут уже можно проверять наличие окна. Если его нет, то уже и не будет.
...
m_mutexOneInstance.Release(); //Надо освободить захваченный мьютекс, дабы остальным экземплярам дать поработать
} else {
//Что-то пошло через задницу
}
}
Автор: V0lt
Дата сообщения: 26.10.2011 22:21
wasilissk, Abs62
Понемногу начинаю въезжать, пробный вариант даже работает . Есть немного смутное понимание WAIT_ABANDONED, это ведь когда процесс случайно убился?


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

Добавлено:
В общем MPC такое умеет. Меряет время.

Код: if (last_run && ((GetTickCount()-last_run)<500)) {
    s.nCLSwitches |= CLSW_ADD;
}
last_run = GetTickCount();
Автор: Abs62
Дата сообщения: 26.10.2011 22:38
V0lt

Цитата:
Есть немного смутное понимание WAIT_ABANDONED, это ведь когда процесс случайно убился?

Ну да. Точнее, когда поток завершился, а мьютекс перед этим не освободил. Обычно такое случается именно при падении.
Автор: DmitryKz
Дата сообщения: 02.11.2011 14:00
Не знаю наверняка, по теме ли мои вопросы, но рискну задать здесь:
1. Скажите, пожалуйста, как определить, используется ли Aero в данный момент?
2. Windows 7 при использовании некоторых программ переключает оформление из Aero в Basic, якобы из-за проблем совместимости. Тем не менее, мои наблюдения показывают, что некоторый софт отлично работает и в Aero, а иногда это даже может дать дополнительное удобство (был один такой случай).
Как можно предотвратить переключение оформления?
Можно, конечно, перезапустить службу UxSms, как я и делал раньше, но всё это ценой дополнительного мелькания, которое, вообще-то, не нужно.
Я так понимаю, что у оси есть либо какая-то БД, где хранится список приложений, либо у самого приложения где-то прописано, что необходимо переключение оформления.
Есть ли у кого-либо какие-либо соображения по этому поводу? То есть задача не избавиться от переключения оформления вообще, а только в случае конкретного приложения.
Автор: Molniev
Дата сообщения: 02.11.2011 19:36
DmitryKz,
1. Функция DwmIsCompositionEnabled не то, что вы ищете?
И "какие-либо соображения по этому поводу":
2. А если эта программа вызовет DwmEnableComposition? Но вроде как композитный рабочий стол отключаеться только при использовании старого api (+список совместимости программ +чекбокс в свойствах>совместимость), поэтому если выключается - то уже не включиться.
Автор: ItsJustMe
Дата сообщения: 03.11.2011 13:30

Цитата:
Я так понимаю, что у оси есть либо какая-то БД, где хранится список приложений, либо у самого приложения где-то прописано, что необходимо переключение оформления.

Все проще - переключение происходит, если прога использует API, не совместимый с композитным десктопом. Обычно это интерфейсы DX.
Автор: V0lt
Дата сообщения: 12.12.2011 04:49
Давно хотел спросить. Как поменять цвет фона и текста у контекстного меню?
Автор: ShIvADeSt
Дата сообщения: 12.12.2011 06:26
V0lt
Либо на уровне винды через цветовые схемы (глобально для всех менюшек), либо для своего приложения для своего меню через собственную отрисовку пунктов - WM_DRAWITEM, WM_MEASUREITEM и естессно пункты меню должны быть owner_draw.
Автор: V0lt
Дата сообщения: 12.12.2011 16:52
ShIvADeSt

Цитата:
либо для своего приложения для своего меню через собственную отрисовку пунктов - WM_DRAWITEM, WM_MEASUREITEM и естессно пункты меню должны быть owner_draw.

Чего-то перемудрено только ради смены цвета. Хорошие примеры в инете встречаются?
Автор: Garrett
Дата сообщения: 12.12.2011 17:16
V0lt
Посмотрите на codeproject'e.
Автор: DmitryKz
Дата сообщения: 26.12.2011 10:13
Подскажите по такому вопросу:
есть функция GetOpenFileName, есть хук-процедура - как в хук-процедуре принудительно открывать другие директории? У меня в диалоговом окне пара радио-кнопок, по выбору которых должны открываться определенные директории (чтобы пользователя не заставлять щелкать многажды)..
Прочитал главу в MSDN Open and Save As Dialog Boxes, но информация там не касается этого момента, а каких-либо отсылок в нужном направлении не увидел...
Автор: Abs62
Дата сообщения: 26.12.2011 16:01
DmitryKz
Можно, думаю, занести путь к искомой папке в поле ввода и программно нажать OK (послать этой кнопке WM_LBUTTONDOWN, например, или сымитировать нажатие Enter через WM_KEYDOWN/WM_KEYUP).
Автор: Maks150988
Дата сообщения: 27.12.2011 12:55
Да, это самое то. Только я бы использовал PostMessage с BN_CLICKED. И очистил поле ввода имени файла после этого, чтобы было аккуратненько. =)
Автор: V0lt
Дата сообщения: 14.01.2012 23:19
удалено
Автор: HNKTO
Дата сообщения: 04.03.2012 09:07
Может кто знает:
Какими функциями можно в операционке переключать раскладки клавиатуры, установки раскладки по умолчанию, добавления-удаления раскладок из списка активных?
Кто в курсе - укажите направления поиска.
Всем спасибо.
Автор: akaGM
Дата сообщения: 04.03.2012 09:46
HNKTO

Цитата:
укажите направления поиска
направление всегда одно: MSDN
ставь DDK и играйся...
Автор: Abs62
Дата сообщения: 04.03.2012 11:22
akaGM

Цитата:
ставь DDK

Не надо так человека пугать. Не DDK, а SDK.

HNKTO
Правильно сказали - MSDN. Идёшь в раздел Keyboard Input и выбираешь, что надо.
Автор: akaGM
Дата сообщения: 04.03.2012 15:22
может у него клава какая-нибудь хитрая и он дрова её строгает...
а вообще, просто "последняя осень" :) в shuffle моде прислалась...
Автор: HNKTO
Дата сообщения: 04.03.2012 20:46
Abs62, спасибо.
Понятно, что в MSDN.
Но я как-бы чайник, а MSDN оччень большой. там какую-нить функцию (из абсолютно мне не знакомого раздела) можно искать очень долго.

akaGM, развеиваю твоё любопытство:
хочу написать программу, автоматически перенастраивающую раскладку клавиатуры перед запуском целевой программы (в конкретном случае компьютерной игры) на для этой программы спецефичную, и возвращающей всё на место по выходу из программы.
Автор: Abs62
Дата сообщения: 04.03.2012 21:17
HNKTO
Дык, раздел-то небольшой. И всего шесть функций для работы с раскладками.
По факту для такой задачи, думаю, могут пригодиться:
GetKeyboardLayout - возвращает текущую раскладку для конкретного потока.
LoadKeyboardLayout - загружает нужную раскладку.
ActivateKeyboardLayout - делает указанную раскладку активной.
UnloadKeyboardLayout - выгружает ранее загруженную раскладку.
Автор: kenny5705
Дата сообщения: 19.05.2012 15:38
Странно, почему не хочет работать CreateFile в VS2010...
Вот та часть кода:
......
HANDLE hD = INVALID_HANDLE_VALUE;
    hD = CreateFile(
        (LPCWSTR)"\\\\.\\C:",
        GENERIC_READ,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        0,
        NULL);
    if( hD == INVALID_HANDLE_VALUE )
    {
        cout << "Error is: " << GetLastError() << endl;
        return false;
    };
.......
return true;
.......

И само собой возвращает false, вместо того чтобы возвратить true.
GetLastError показывает ошибку с кодом 2, что соответствует:
ERROR_FILE_NOT_FOUND - 2 (0x2) - The system cannot find the file specified.

При этом в другом компиляторе (MiniGW GCC) замечательно работает...
Может я не так как-то запускаю?

Еще может кто знает, как в Dev-Cpp сделать полную поддержку winapi, а то, как оказалось, не все функции и структуры он понимает (например, увидев имя структуры STORAGE_DEVICE_NUMBER кричит "'STORAGE_DEVICE_NUMBER' was not declared in this scope" и отказывается с ней работать)
Автор: Abs62
Дата сообщения: 19.05.2012 16:04
kenny5705

Цитата:
(LPCWSTR)"\\\\.\\C:"

Вот так делать нельзя. Если функция требует юникодную строку, ей и надо давать такую строку, а не обманывать приведением указателя.

Код: CreateFileW(L"\\\\.\\C:",...
или
CreateFile(_T("\\\\.\\C:"),...

Страницы: 12345678910111213141516171819202122232425262728293031323334353637

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


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