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

» C++ WinAPI

Автор: TeXpert
Дата сообщения: 18.11.2006 21:55
Thritt
Он там ещё приводит команды для компиляции и сборки.

Но самый простой способ -- воспользоваться прагмой линкера
#pragma comment(lib, "winmm")
Эту строчку вставь прямо в код где-то вначале файла.
Автор: Thritt
Дата сообщения: 19.11.2006 11:35
TeXpert
спасибо за помощь!
Автор: Thritt
Дата сообщения: 20.11.2006 21:02
У меня вопрос: создаю кнопку стиля BS_OWNERDRAW

case WM_CREATE:
Btn1 = CreateWindowW(TEXT("BUTTON"), NULL, WS_CHILD|WS_VISIBLE|BS_OWNERDRAW,
    100, 130, 130, 35,hWnd, (HMENU)ID_BTN1, hInst, NULL);
break;

затем рисую на кнопке битмап и хочу сделать так, что если щелкнуть по кнопке то во время щелчка на кнопке должна отображаться другая картинка:

case WM_DRAWITEM:
pdis = LPDRAWITEMSTRUCT(lParam);
cbtndc = CreateCompatibleDC(pdis->hDC);
SelectObject(cbtndc, bm1);    
BitBlt(pdis->hDC, 0, 0, 130, 35, cbtndc, 0, 0, SRCCOPY);
if (pdis->itemState & ODS_SELECTED)
{
    SelectObject(cbtndc, bm2);
    BitBlt(pdis->hDC, 0, 0, 130, 35, cbtndc, 0, 0, SRCCOPY);
}
ReleaseDC(Btn1, cbtndc);
break;

И вот вопрос: почему когда я щелкаю по кнопке то вторая картинка остается, хотя она должна отображаться только во время нажатия на кнопку? кнопка остается как бы нажатой и "отжать" обратно ее нельзя.

HWND Btn1;
HBITMAP bm1 = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP1));
HBITMAP bm2 = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_BITMAP2));
HDC cbtndc;
LPDRAWITEMSTRUCT pdis;
Автор: Collapse_Troll
Дата сообщения: 20.11.2006 21:54
Здравствуйте! Дайте пожалуйста пример получения статуса CD-привода (то есть лоток открыт либо закрыт). А то у самого не получается.

Программа из FAQ по С++ Builder. Получаю статус CD-ROM-а, постоянно возвращается " Current mode is 'open' ", незаваисимо от того, открыт сидюк или нет. Как правильно? Вот код:
[more]

Код: //---------------------------------------------------------------------------

#include <vcl.h>
#include <mmsystem.h>
#include <stdio.h>

#pragma comment(lib,"winmm.lib")

//---------------------------------------------------------------------------

/* Создание команды без указания имени CD-ROM'а */
char * CreateCdCommand(char * pBuffer, char * pCommand, char * pCmdFlags, char * pFlags) {
sprintf(pBuffer,"%s cdaudio %s %s",pCommand,pCmdFlags,pFlags);
return pBuffer;
}

/* Создание команды с указанием имени CD-ROM'а */
char * CreateCdCommandEx(char * pBuffer, char DriveLetter, char * pCommand, char * pCmdFlags, char * pFlags) {
sprintf(pBuffer,"%s cdaudio!%c: %s %s",pCommand,DriveLetter,pCmdFlags,pFlags);
return pBuffer;
}


WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
Application->Initialize();
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}




// Управление CD-ROM'ом:

/* Команды */
char * CdCmdSet = "set";
char * CdCmdStatus = "status";
char * CdCmdPlay = "play";
char * CdCmdPause = "pause";
char * CdCmdStop = "stop";
char * CdCmdResume = "resume";

/* Флаги команд */
char * CdCmdFlagOpen = "door open";
char * CdCmdFlagClose = "door closed";
char * CdCmdCurTrack = "current track";
char * CdCmdCurMode = "mode";
char * CdCmdFlagEmpty = "";

/* Флаги выполнения */
char * CdFlagWait = "wait";
char * CdFlagEmpty = "";

/* Буфер, в котором будем создавать команды */
char CdCommandBuffer[256];



//Получить текущее состояние, ожидая выполнения этой команды:
mciSendStringA(CreateCdCommand(CdCommandBuffer,CdCmdStatus,CdCmdCurMode,CdFlagWait),
        CdCommandBuffer,
        255,
        INVALID_HANDLE_VALUE);

ShowMessage(CdCommandBuffer); // здесь выдается статус сидюка (открыт, закрыт и что-то еще)



/* //Открыть CD-ROM, ожидая выполнения этой команды:
mciSendStringA(CreateCdCommand(CdCommandBuffer,CdCmdSet,CdCmdFlagOpen,CdFlagWait),
        NULL,
        0,
        INVALID_HANDLE_VALUE);


//Закрыть CD_ROM, ожидая выполнения этой команды:
mciSendStringA(CreateCdCommand(CdCommandBuffer,CdCmdSet,CdCmdFlagClose,CdFlagWait),
        NULL,
        0,
        INVALID_HANDLE_VALUE);
*/


//Если в системе присутствует несколько приводов CD, то для задания конкретного
//привода вместо функции CreateCdCommand следует использовать CreateCdCommandEx

return 0;

}
Автор: ShIvADeSt
Дата сообщения: 21.11.2006 00:53
Thritt

Цитата:
У меня вопрос: создаю кнопку стиля BS_OWNERDRAW

в свое время переводил его на дельфи и все работало как надо
[more]
LRESULT APIENTRY OwnDrawProc(hDlg, message, wParam, lParam)
HWND hDlg; // window handle of dialog box
UINT message; // type of message
UINT wParam; // message-specific information
LONG lParam;
{
HDC hdcMem;
LPDRAWITEMSTRUCT lpdis;

switch (message) {
case WM_INITDIALOG:

// hinst, hbm1 and hbm2 are defined globally.
hbm1 = LoadBitmap((HANDLE) hinst, "OwnBit1");
hbm2 = LoadBitmap((HANDLE) hinst, "OwnBit2");

return TRUE;

case WM_DRAWITEM:
lpdis = (LPDRAWITEMSTRUCT) lParam;
hdcMem = CreateCompatibleDC(lpdis->hDC);

if (lpdis->itemState & ODS_SELECTED) // if selected
SelectObject(hdcMem, hbm2);
else
SelectObject(hdcMem, hbm1);

// Destination
StretchBlt(
lpdis->hDC, // destination DC
lpdis->rcItem.left, // x upper left

lpdis->rcItem.top, // y upper left

// The next two lines specify the width and
// height.
lpdis->rcItem.right - lpdis->rcItem.left,
lpdis->rcItem.bottom - lpdis->rcItem.top,
hdcMem, // source device context
0, 0, // x and y upper left
32, // source bitmap width
32, // source bitmap height

SRCCOPY); // raster operation

DeleteDC(hdcMem);
return TRUE;

case WM_COMMAND:
if (wParam == IDOK
|| wParam == IDCANCEL) {
EndDialog(hDlg, TRUE);
return TRUE;
}
if (HIWORD(wParam) == BN_CLICKED) {
switch (LOWORD(wParam)) {
case IDB_OWNERDRAW:

.
. // application-defined processing

.

break;
}
}
break;

case WM_DESTROY:
DeleteObject(hbm1); // delete bitmaps
DeleteObject(hbm2);

break;

}
return FALSE;
UNREFERENCED_PARAMETER(lParam);
}
[/more]
тебе ничего переводить не надо, просто разберись.
Автор: tomegadeth
Дата сообщения: 21.11.2006 09:23
Collapse_Troll
здесь все гораздо проще
зы - иногда полезно юзать Версия для печати
Автор: Astraalfa
Дата сообщения: 21.11.2006 11:44
Поскажите ,пожалуйста, как загрузить gif-анимашку на окно средствами WinApi?
Автор: daMIR
Дата сообщения: 21.11.2006 22:53
Помогите с API- для меня это новая тема Нужно в общем появление окошка с выбором директории, наподобии команды "открыть" в программах, точнее кнопка "обзор" В программе я буду использовать путь до папки котрую выберу. Какую для этого необходимо использвать функцию, какие параметры казывать и в какой длл-ке она находится? Искал в теме- ответа не нашел. В справочнике нашел:

Цитата:

Функция GetSystemDirectory
Описание:
function GetSystemDirectory(Buffer: PChar; Size: Word);
Получает имя маpшpута для подкаталога системы Windows.
Паpаметpы:
Buffer: Пpинимающий буфеp.
Size: Размеp буфеpа (не менее 144 символов).
функция находится в файле kernel32.dll

Непонятно как/какой указать буфер, да и остальные праметры тож.
Автор: TeXpert
Дата сообщения: 21.11.2006 23:45
daMIR
Можно SHBrowseForFolder использовать.
Ссылка в MSDN:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/functions/shbrowseforfolder.asp
Там же вся информация с примерами.
Автор: butsefal
Дата сообщения: 22.11.2006 05:14
Помогите новичку разобраться с копированием данных из другой программы. Имеется программа, которая выводит данные в окно в виде списка, доступа к коду нет, окно не текстовое, видимо. В этом окне строку можно выбрать либо мышкой, либо стрелками вниз-вверх и скопировать через Ctrl-C на Cipboard. Оттуда их потом легко достать.
Я пытаюсь этот процесс автоматизировать. Написал программу, которая а). находит хэндл окна, б). посылает ему SetForegroundWindow, в). через PostMessage сдвигает курсор на нужную строку в списке. Далее я пытался ему засылать через PostMessage последовательность:
VK_CONTROL , WM_KEYDOWN ; VK_C, WM_KEYDOWN; VK_C, WM_KEYUP; VK_CONTROL, WM_KEYUP,
то есть, эмулировать Ctrl-C. На Clipboard ничего не копируется (я проверяю через Ctrl-V в текстовый редактор). Если же я физически нажимаю на клаве Ctrl-C, то строка копируется.
Я решил проверить через WinSpector сообщения, которые уходят окну при эмуляции Ctrl-C и при физическом нажатии на клаве, они те же самые, что и выше в обоих случаях ... Проверил, что родителям этого окна никакой информации при копировании не передаётся. В чём же дело и почему моя эмуляция не работает ?
Автор: xdude
Дата сообщения: 22.11.2006 05:40
butsefal
А не легче для хэндла этого списка сделать GetWindowText ? Хотя, не знаю, сработает ли это для списка, но что точно сработает - так это LB_GETTEXT, LB_GETCOUNT и иже с ними. Если не получается сделать это из другого процесса - можно внедрить поток в нужный процесс, используя CreateRemoteThread. В общем, MSDN в помощь
Автор: butsefal
Дата сообщения: 22.11.2006 06:55
Я не знаю как организованы данные в списке в этом окне. Список состоит из строк, которые можно копировать через Ctrl-C. Я запустил Windows Scanner от InqSoft и он не может извлечь из этого окна никаких данных вообще, текста там точно нет через GetWindowText.
И это не ListBox, WindowsClass окна: WindowsForms10.Window.8.app61 Конечно, я предпочёл бы извлечь с помощью каких-то сообщений, посланных окну, но оно не отзывается на никакие ...GETTEXT, может я не знаю как спросить ... Да, и у окна нет childs.
Автор: Qraizer
Дата сообщения: 22.11.2006 11:49
Попробуй вместо нажатий на кнопки послать приложению WM_COPY. Правда, в MSDN написано, что это для эдитов и комбиков, но мало ли, вдруг поможет.
Автор: TeXpert
Дата сообщения: 22.11.2006 12:30
butsefal
А Spy++ что говорит?
Автор: butsefal
Дата сообщения: 22.11.2006 13:19
Я использовал Winspector, который аналог Spy++, он мне больше нравится. Он ничего не говорит, окно вообще выглядит графическим, listbox, editbox, combobox и т.д. не катят. Вообщем после долгих танцев с бубном мне удалось сэмулировать захват на Clipboard c Ctrl-C через keybd_event сообщения. Пока не до конца понял как там двигаться по списку и делать захват в заданном месте, но удалось вытащить строки из середины списка. Почему не срабатывает PostMessage окну, я не знаю.
Автор: daMIR
Дата сообщения: 22.11.2006 23:10
TeXpert
По ссылке на англицком к сожалению- я ни бум-бум . Нашел правда что-то http://cbuilder.ru/faqs/bcbfaq/Allow%20the%20user%20to%20browse%20for%20a%20folder.html
Там написано что будет возвращаться какой-то пидл, и как я понял нужно повозиться чтоб преоброзовать его в путь. Плюс его еще как-то "очищать" надо...
Автор: ShIvADeSt
Дата сообщения: 23.11.2006 01:06
butsefal
вот здесь подробно все обсуждалось
http://forum.ru-board.com/topic.cgi?forum=33&topic=4297&start=280

Добавлено:
daMIR
Однако учимся юзать фильтр
http://forum.ru-board.com/topic.cgi?forum=33&topic=2042#1
Автор: Collapse_Troll
Дата сообщения: 26.11.2006 15:31
tomegadeth
прошу прощения что затянул с ответом. Спасибо, но мне нужно знать, открыт сидюк в данный момент или нет:

Если сидюк открыт - то закрыть
Если сидюк закрыт - соответственно открыть.

Так как узнать его текущее состояние?
Автор: tomegadeth
Дата сообщения: 26.11.2006 18:07
Collapse_Troll
Цитата:
Получаю статус CD-ROM-а, постоянно возвращается " Current mode is 'open' ", незаваисимо от того, открыт сидюк или нет.
знакомые грабли... так будет всегда, даже если лоток закрыт но в нем нет компакт-диска...
можно попробовать, проверить статус привода. и если он "open", вызвать метод который закрывает привод. Если выход из метода слишком быстрый (придется настроить по времени) значит лоток и так был закрыт и сразу вызываем метод открытия привода. Не самое красивое решение - но самое простое. Сложнее - через ASPI или для ос-ей NT, XP и выше - DeviceIoControl.
Автор: Collapse_Troll
Дата сообщения: 26.11.2006 21:48
tomegadeth
понял, отличная идея, спасибо! =)
Автор: HANDLE
Дата сообщения: 27.11.2006 05:11
daMIR

Цитата:
Нужно в общем появление окошка с выбором директории,



Код:
#include <shlobj.h>

int CALLBACK ExpandFolder(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
if (uMsg == BFFM_INITIALIZED)
{
::SendMessage(hWnd, BFFM_SETSELECTION, 1, lpData);
}
return 0;
}

void CRandomStringDlg::OnBnClickedOk()
{
TCHAR szPath[MAX_PATH];
lstrcpy(szPath, lpLastPath); // папка, которую хотим развернуть в дереве

BROWSEINFO bi = { 0 };
bi.hwndOwner = m_hWnd; // окно, куда будут посылаться сообщения
bi.lpszTitle = _T("Выбор ...."); // пояснительная надпись
bi.ulFlags = BIF_NEWDIALOGSTYLE; // флаги
bi.lpfn = ExpandFolder; // call-back
bi.lParam = (LPARAM)szPath; //

LPITEMIDLIST lpItemIdList = SHBrowseForFolder(&bi);
if (lpItemIdList)
{
if (SHGetPathFromIDList(lpItemIdList, szPath))
{
// действия с выбранной папкой

}

// освобождаем память
IMalloc *pMalloc;
if (SUCCEEDED(SHGetMalloc(&pMalloc)))
{
pMalloc->Free(lpItemIdList);
pMalloc->Release();
}
}

// а если указать корневую папку, то выбирать можно только внутри её
#include <shfolder.h>

// Выбираем только внутри %PROGRAMFILES%
LPITEMIDLIST lpRootItemIdList;
SHGetSpecialFolderLocation(m_hWnd, CSIDL_PROGRAM_FILES, &lpRootItemIdList);
bi.pidlRoot = lpRootItemIdList;
Автор: linder
Дата сообщения: 27.11.2006 07:51
Подскажите пожалуйста как записать звук (речь) с микрофона в Visual C++
Желательно приведите пример программы реализующей это, или подскажите
где про это можно почитать...

а следующий шаг для меня быстрое преобразование фурье и получение спектра!
Автор: vkarpov1968
Дата сообщения: 27.11.2006 09:19
Всем привет.
Требуется помощь. C++Builder. Надо написать передачу строки между приложениями. Был выбран самый простой вариант - через SendMessage
передающая часть:
HWND hApp = FindWindow(NULL, "Form1");
if (hApp!=0)
{
COPYDATASTRUCT cds;
cds.dwData = 1;
cds.cbData = strlen(CmdLine);
cds.lpData = CmdLine;

SendMessage(HWND_BROADCAST, WM_COPYDATA, NULL, (LPARAM)&cds);

}

А вот с приёмником проблема
было опробовано 2 варианта
1. перехватчик Application->OnMessage
2. Application->HookMainWindow()

ни до одной функции сообщение не доходит, хотя сообщение WM_CLOSE до приложения доходит легко.
Что делать, в каком месте поймать сообщение????
Автор: tomegadeth
Дата сообщения: 27.11.2006 09:26
vkarpov1968 копни в сторону [more=RegisterWindowMessage]The RegisterWindowMessage function is typically used to register messages for communicating between two cooperating applications.

If two different applications register the same message string, the applications return the same message value. The message remains registered until the session ends.

Only use RegisterWindowMessage when more than one application must process the same message. For sending private messages within a window class, an application can use any integer in the range WM_USER through 0x7FFF. (Messages in this range are private to a window class, not to an application. For example, predefined control classes such as BUTTON, EDIT, LISTBOX, and COMBOBOX may use values in this range.)[/more]

Добавлено:
решение через WM_COPYDATA
Автор: vkarpov1968
Дата сообщения: 27.11.2006 10:42
tomegadeth
Спасибо огромное. COPYDATA в таком варианте работает.
А RegisterWindowMessage работает, только отсылать надо PostMessage - тогда доходит, но свою структуру не передать, только циферки.
Автор: Collapse_Troll
Дата сообщения: 29.11.2006 02:10
tomegadeth
программу управления сидюком сделал, работает. Если лоток сидюка уже внутри, то выход из метода закрытия происходит либо за секунду, либо за меньший промежуток. Но если жмакать на кнопку на самом сидюке то выезжает/заезжает быстрее. Может влияют другие обращения к сидюку(автозапуск, таблички "Какое действие с диском следует выполнять Windows?") Может можно как-то экстренно закрывать/открывать сидюк, не обращая внимание на то, есть ли к нему обращение или нет? Пробовал убирать 'wait' из
Код: mciSendString("Set cdaudio door open wait", NULL, 0, NULL);
Автор: TeXpert
Дата сообщения: 29.11.2006 04:02
Collapse_Troll
ЁRD Commander, например, наглухо блокирует кнопку CD/DVD. Как это она делает? Очевидно, есть какие-то команды, думаю, через DeviceIOControl можно выйти на них.
Автор: ShIvADeSt
Дата сообщения: 29.11.2006 05:07
TeXpert

Цитата:
ЁRD Commander, например, наглухо блокирует кнопку CD/DVD. Как это она делает?

аналогично блокирует и нера когда пишет диск, возможно перехватывают вызовы АПИ функций, либо есть другие команды, которые позволяют игнорировать.
Автор: tomegadeth
Дата сообщения: 29.11.2006 09:39
вот - но работать будет только под
Цитата:
Windows Vista, Windows XP, Windows 2000 Professional, or Windows NT Workstation 4.0.
наглухо заблокирует девайс.....


Код: #include <windows.h>
#include <Winioctl.h>

unsigned long LockCD(char drive, bool lockdrive)
{
    unsigned long junk, lResult;
    char drv[8] = {'\\', '\\', '.', '\\', drive, ':', 0};
    
    PREVENT_MEDIA_REMOVAL pmr = {lockdrive};
    
    void * hDevice = CreateFile(drv, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    
    if(hDevice != INVALID_HANDLE_VALUE)
    {
        if(GetDriveType(&drv[4]) == DRIVE_CDROM)
            lResult = DeviceIoControl(hDevice, IOCTL_STORAGE_MEDIA_REMOVAL, &pmr, sizeof(pmr), NULL, 0, &junk, 0);
        CloseHandle(hDevice);
    }
    
    return lResult;
}

void main()
{
    LockCD('f', true); // блокирует
    LockCD('f', false); // разблокирует
}
Автор: daMIR
Дата сообщения: 29.11.2006 11:21
Если честно мне все равно мало понятны эти листинги, может подскажите названия справочников/учебников по API? Искал через поисковик, но ничего толкового не нашел. А втыкать эту конструкцию я вообще собирался в Форт..

Страницы: 12345678910111213141516171819202122232425262728293031323334353637

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


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