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

» C++ WinAPI

Автор: Abs62
Дата сообщения: 18.03.2008 20:19
VictorMi

Цитата:
After SetClipboardData is called, the system owns the object identified by the hMem parameter. The application can read the data, but must not free the handle or leave it locked until the CloseClipboard function is called.

То бишь после формирования строки сначала надо сделать GlobalUnlock, только после этого SetClipboardData, и затем CloseClipboard. А дальше система сама разберётся, что с этим хэндлом делать.
Автор: cartman007
Дата сообщения: 19.03.2008 11:51
Подскажите пожайлуста как будет выглядеть скрипт(простой батничек) для копирования папки с файлами на указанное место.
Например надо скопировать папку с данными с пути C:Новая папка в диск G: и чтобы на экран процесс копирования не выводился.
И если можно то сделать так чтобы если вдруг скрипт был запущен второй раз и будет производиться вторая попытка копирования файлов то те которые были скопированы будут просто замещены.
я попробовал такой
md G:/papka
copy /Y C:/papka/*.* G:/papka
но выдает ошибку в синтаксисе
Заранее спасибо за ответ!!!
Автор: Djony1987
Дата сообщения: 19.03.2008 12:33
Такой вопрос: как мне проверять находится ли мышь в данном окне при нажатии или нет?
Поискал функцию..так и не смог найти...а через координаты запутался жестко((
Автор: Abs62
Дата сообщения: 19.03.2008 18:37
cartman007
Батники рассматриваются в этой теме.

Djony1987
Вообще-то, при нажатии кнопки сообщение отправляется именно тому окну, над которым находится указатель (если мышь не захвачена). Если нужно определить попадает ли указатель в конкретную область, придётся таки разобраться с координатами, посмотреть функции PtInRect, PtInRegion и т.д.
Автор: Djony1987
Дата сообщения: 20.03.2008 13:10
Abs62
Спасибо! Начал токо недавно осваивать API (в ВУзе всмысле). Поэтому прошу сильно не пинать.
Задание было следующие: Углы рабочей области окна приложения полностью занимают 4 временных окна одного класса. Если нажать левую клавишу мыши над временным окном, то это окно выдает сообщение о своем заголовке.

Листинг моей проги:

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

#include <windows.h>
#include <vcl.h>
#pragma hdrstop

//---------------------------------------------------------------------------
LRESULT CALLBACK HelloWorldWndProc(HWND, UINT, UINT, LONG);
HWND hChildWind_1, hChildWind_2, hChildWind_3, hChildWind_4;
char szClassName[]="Hello World!";
char nameWnd[4][18]={"Временное окно №1","Временное окно №2","Временное окно №3","Временное окно №4"};
MSG Msg;
RECT R;
int x1,x2,y1,y2;
TPoint p;

int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdParam,
int nCmdShow)
{
HWND hWnd;
WNDCLASS WndClass;
WndClass.style=CS_HREDRAW | CS_VREDRAW;
WndClass.lpfnWndProc=HelloWorldWndProc;
WndClass.cbClsExtra=0;
WndClass.cbWndExtra=0;
WndClass.hInstance=hInstance;
WndClass.hIcon=LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor=LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.lpszMenuName=NULL;
WndClass.lpszClassName=szClassName;

if(!RegisterClass(&WndClass))
{
MessageBox(NULL, "Невозможно зарегистрировать класс", "Ошибка!!", MB_OK);
return 0;
}

hWnd=CreateWindow(szClassName, "Прога №1", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);

if(!hWnd)
{
MessageBox(NULL, "Невозможно создать окно", "Ошибка!!", MB_OK);
return 0;
}

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

int w=GetSystemMetrics(SM_CYCAPTION);
GetWindowRect(hWnd,&R);
x1=R.left;
y1=R.top+w;
x2=R.right;
y2=R.bottom;

hChildWind_1=CreateWindow(szClassName, nameWnd[0], WS_OVERLAPPEDWINDOW | WS_POPUP,
x1, y1, (x2-x1)/2, (y2-y1)/2,
hWnd, NULL, hInstance, NULL);

if(!hChildWind_1)
{
MessageBox(NULL, "Невозможно создать окно", "Ошибка!!", MB_OK);
return 0;
}

ShowWindow(hChildWind_1, SW_SHOW);
UpdateWindow(hChildWind_1);

hChildWind_2=CreateWindow(szClassName, nameWnd[1], WS_OVERLAPPEDWINDOW | WS_POPUP,
x1+(x2-x1)/2, y1+(y2-y1)/2, (x2-x1)/2, (y2-y1)/2,
hWnd, NULL, hInstance, NULL);

if(!hChildWind_2)
{
MessageBox(NULL, "Невозможно создать окно", "Ошибка!!", MB_OK);
return 0;
}

ShowWindow(hChildWind_2, SW_SHOW);
UpdateWindow(hChildWind_2);

hChildWind_3=CreateWindow(szClassName, nameWnd[2], WS_OVERLAPPEDWINDOW | WS_POPUP,
x1, y1+(y2-y1)/2, (x2-x1)/2, (y2-y1)/2,
hWnd, NULL, hInstance, NULL);

if(!hChildWind_3)
{
MessageBox(NULL, "Невозможно создать окно", "Ошибка!!", MB_OK);
return 0;
}

ShowWindow(hChildWind_3, SW_SHOW);
UpdateWindow(hChildWind_3);

hChildWind_4=CreateWindow(szClassName, nameWnd[3], WS_OVERLAPPEDWINDOW | WS_POPUP,
x1+(x2-x1)/2, y1, (x2-x1)/2, (y2-y1)/2,
hWnd, NULL, hInstance, NULL);

if(!hChildWind_4)
{
MessageBox(NULL, "Невозможно создать окно", "Ошибка!!", MB_OK);
return 0;
}

ShowWindow(hChildWind_4, SW_SHOW);
UpdateWindow(hChildWind_4);

while(GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
LRESULT CALLBACK HelloWorldWndProc(HWND hWnd, UINT Message, UINT wParam, LONG lParam)
{
HDC hDC;
PAINTSTRUCT PaintStuct;
RECT Rect;

switch(Message)
{
case WM_LBUTTONDOWN:
{
GetCursorPos(&p);
int xm=p.x;
int ym=p.y;
//AnsiString a,b;
GetWindowRect(hChildWind_1, &Rect);
//a=IntToStr(xm)+" "+IntToStr(ym);
//ShowMessage(a);
//b=IntToStr(Rect.left)+" "+IntToStr(Rect.right)+" "+IntToStr(Rect.top)+ " "+IntToStr(Rect.bottom);
//ShowMessage(b);
if((xm>Rect.left) && (xm<Rect.right) && (ym>Rect.top) && (ym<Rect.bottom))
MessageBox(NULL, nameWnd[0], "Прога №1", MB_OK);
GetWindowRect(hChildWind_2, &Rect);
if((xm>Rect.left)&&(xm<Rect.right)&&(ym>Rect.top)&&(ym<Rect.bottom))
MessageBox(NULL, nameWnd[1], "Прога №1", MB_OK);
GetWindowRect(hChildWind_3, &Rect);
if((xm>Rect.left)&&(xm<Rect.right)&&(ym>Rect.top)&&(ym<Rect.bottom))
MessageBox(NULL, nameWnd[2], "Прога №1", MB_OK);
GetWindowRect(hChildWind_4, &Rect);
if((xm>Rect.left)&&(xm<Rect.right)&&(ym>Rect.top)&&(ym<Rect.bottom))
MessageBox(NULL, nameWnd[3], "Прога №1", MB_OK);
return 0;
}
case WM_DESTROY:
if (hWnd != hChildWind_1 && hWnd !=hChildWind_2 && hWnd !=hChildWind_3 && hWnd !=hChildWind_4)
             PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd, Message, wParam, lParam);
}
return 0;
}

//---------------------------------------------------------------------------
Автор: Abs62
Дата сообщения: 20.03.2008 19:32
Djony1987
Ага, неправильно.
Я бы делал так:
1. Создал и зарегистрировал класс главного окна.
2. Создал и зарегистрировал класс вспомогательного окна (почему оно называется временным, кстати?).
3. В обработчике сообщения WM_CREATE главного окна создал бы четыре вспомогательных окна (рекомендую, кстати, для определения размеров клиентской области использовать GetClientRect - это сразу даст нужные координаты, а с GetWindowRect мороки будет куда больше ) класса из п.2 со стилем WS_CHILD (а не WS_OVERLAPPEDWINDOW и не WS_POPUP!). И задал бы каждому свой заголовок.
4. В обработчике сообщений вспомогательного окна ловил бы WM_LBUTTONDOWN, вытаскивал бы заголовок (GetWindowText) и показывал бы его.

Вот, слегка подкрутил исходник, для лучшего понимания.
[more]//---------------------------------------------------------------------------

#include <windows.h>

//---------------------------------------------------------------------------
LRESULT CALLBACK HelloWorldWndProc(HWND, UINT, UINT, LONG);
LRESULT CALLBACK SecondWndProc(HWND, UINT, UINT, LONG);

HWND hChildWind_1, hChildWind_2, hChildWind_3, hChildWind_4;
const char *szMainClassName="Hello World!";
const char *szSecondClassName="Second window";
const char *nameWnd[4]={"Временное окно №1","Временное окно №2","Временное окно №3","Временное окно №4"};
MSG Msg;
RECT R;
int x1,x2,y1,y2;
WNDCLASS WndSecondClass;

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

int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdParam,
int nCmdShow)
{
HWND hWnd;
WNDCLASS WndClass;
WndClass.style=CS_HREDRAW | CS_VREDRAW;
WndClass.lpfnWndProc=HelloWorldWndProc;
WndClass.cbClsExtra=0;
WndClass.cbWndExtra=0;
WndClass.hInstance=hInstance;
WndClass.hIcon=LoadIcon(NULL, IDI_APPLICATION);
WndClass.hCursor=LoadCursor(NULL, IDC_ARROW);
WndClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
WndClass.lpszMenuName=NULL;
WndClass.lpszClassName=szMainClassName;

if(!RegisterClass(&WndClass))
{
MessageBox(NULL, "Невозможно зарегистрировать класс", "Ошибка!!", MB_OK);
return 0;
}

WndSecondClass.style=CS_HREDRAW | CS_VREDRAW;
WndSecondClass.lpfnWndProc=SecondWndProc;
WndSecondClass.cbClsExtra=0;
WndSecondClass.cbWndExtra=0;
WndSecondClass.hInstance=hInstance;
WndSecondClass.hIcon=LoadIcon(NULL, IDI_APPLICATION);
WndSecondClass.hCursor=LoadCursor(NULL, IDC_ARROW);
WndSecondClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
WndSecondClass.lpszMenuName=NULL;
WndSecondClass.lpszClassName=szSecondClassName;
if(!RegisterClass(&WndSecondClass))
{
MessageBox(NULL, "Невозможно зарегистрировать класс", "Ошибка!!", MB_OK);
return 0;
}

hWnd=CreateWindow(szMainClassName, "Прога №1", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL);

if(!hWnd)
{
MessageBox(NULL, "Невозможно создать окно", "Ошибка!!", MB_OK);
return 0;
}

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

while(GetMessage(&Msg, NULL, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}

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

LRESULT CALLBACK HelloWorldWndProc(HWND hWnd, UINT Message, UINT wParam, LONG lParam)
{
RECT Rect;
int x,y,x0,y0,i;
HWND hw;

switch(Message) {
case WM_CREATE:
GetClientRect(hWnd,&Rect);
x=Rect.right/2;
y=Rect.bottom/2;
for(i=0;i<4;i++) {
x0=(i%2)*x;
y0=(i<2?0:y);
hw=CreateWindow(szSecondClassName,nameWnd[i],WS_CHILD|WS_VISIBLE,x0,y0,x,y,hWnd,NULL,WndSecondClass.hInstance,0);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd, Message, wParam, lParam);
}
return 0;
}

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

LRESULT CALLBACK SecondWndProc(HWND hWnd, UINT Message, UINT wParam, LONG lParam)
{
char Buffer[500];
switch(Message) {
case WM_LBUTTONDOWN:
GetWindowText(hWnd,Buffer,sizeof(Buffer));
MessageBox(GetParent(hWnd),Buffer,"Header",MB_ICONINFORMATION|MB_OK);
return(0);
default:
return DefWindowProc(hWnd, Message, wParam, lParam);
}
}[/more]
Автор: Djony1987
Дата сообщения: 21.03.2008 06:30
Abs62
Спасибо большое!! Прочитал в книге что окна делятся на временные и дочерние. Поэтому наверно здесь WS_CHILD не правильно по заданию. И еще прога не работает как надо почему-то - создается главное окно и все. щелкаешь на углах - выскакивают заголовок а самих временных окон не видно...или ты так и хотел?
Много почерпнул из твоего текста...Сенк!
Автор: Abs62
Дата сообщения: 21.03.2008 09:01
Djony1987

Цитата:
Прочитал в книге что окна делятся на временные и дочерние.

Может, всё-таки всплывающие (Pop-up)?

Цитата:
Поэтому наверно здесь WS_CHILD не правильно по заданию.

Может быть, хотя всплывающие окна так использовать - извращение. Они на то и всплывающие - показал и убрал.
Ну, замени WS_CHILD на WS_POPUP. Только координаты по другому посчитать надо будет - для всплывающих окон они задаются относительно экрана, а не относительно материнского окна, насколько я помню.

Цитата:
а самих временных окон не видно...

Видно. Просто в них ничего не нарисовано, WS_BORDER не задан, WS_CAPTION тоже - вот они никак и не выделяются.

Цитата:
или ты так и хотел?

Ага.
Автор: Djony1987
Дата сообщения: 21.03.2008 20:30
Abs62
Все супер. Спасибо еще раз! Если появятся вопросы еще спрошу)
Автор: MrZeRo
Дата сообщения: 03.04.2008 17:05
Подскажите, пожалуйста, как можно (и можно ли) определить перечень файлов, открытых данным приложением? (ProcessID, ThreadID можно получить если надо).
Автор: o_0
Дата сообщения: 17.04.2008 22:29
Доброго времени суток. Помогите пожалуйста решить проблему.Есть система с двумя мониторами. В системе 2 видеокарты. На каждой висит моник. Можно ли средствами винапи проиграть файл на одном монике причем на втором этот файл не проигрывается?
То есть на одном монике челове работает а на другом проигрывается файл.
Спасибо большое.
Автор: ShIvADeSt
Дата сообщения: 18.04.2008 00:59
o_0
Насчет винапи вряд ли, тут специфика видеокарт. Но так как есть видеоплееры, которые распознают количество мониторов и могут делать вывод на одном только, то как то это можно. Вот только насчет винапи сомневаюсь, мб какое нить SDK.
Автор: ZONE51
Дата сообщения: 18.04.2008 08:27
ShIvADeSt
А можете сказать примеры таких плееров (желательно опенсурс)?
Автор: Qraizer
Дата сообщения: 18.04.2008 17:25
DirectShow это SDK называется. Смотри в разделы, посвящённые перечислению имеющихся устройств (у тебя их будет более одного, если две видеокарты) и управлению оверлеями (если к одной видеокарте подключены два монитора).
Автор: o_0
Дата сообщения: 18.04.2008 23:31
Qraizer
Так я нашел список мониторов не на директ х а используя простое винапи. Это все я сделал. Вопрос в том как теперь проиграть файл этот на конкретном монике. 2 видюхи по монику на каждой
Автор: Qraizer
Дата сообщения: 19.04.2008 15:38
Обычно DirectShow юзает DirectDraw для вывода. Смотри интерфейсы DirectDraw для перечисления доступных устройств. Должен будешь найти 2 устройства. Как это потом связывается с DirectShow - не подскажу, не знаю.

P.S. Через WinAPI в том понимании, как ты это себе представляешь, видео ты в общем случае не проиграешь, т.к. кодеки могут не поддерживать интерфейс VideoForWindows, потому как он устаревший, но обязательно поддерживают DirectShow. Кроме того, DirectX уже давно стал неотделимой частью операционной системы, так что его интерфейсы без большой натяжки можно считать относящимся к WinAPI.
Автор: master20
Дата сообщения: 20.04.2008 17:02
Подскажите лучший учебник, с кот. надо начинать изучение WinAPI
Заранее спасибо
Автор: Abs62
Дата сообщения: 20.04.2008 17:26
master20
Начать лучше с Петзольда - "Программирование для Windows 95". Он даёт материал подробно и с самых азов. Потом стоит пройтись по Рихтеру - "Создание эффективных WIN32-приложений". Далее по потребностям.
Автор: master20
Дата сообщения: 20.04.2008 22:07
Abs62
Спасибо!
Скачал Петзольда, полистал - классный учебник, а вот Рихтера че-то не хочет качать..
Автор: Garrett
Дата сообщения: 20.04.2008 22:50
master20
Рихтер лежит у меня, см. мой профиль, раздел "программы" (ссылка с сайта naumen ведёт на мой сайт).
Там же я положил последнего Петцольда(10-ое изд.) на английском и с примерами.
Автор: master20
Дата сообщения: 20.04.2008 23:50
Garrett
Все в порядке, просто DownloadMaster не хотел качат, пишет:
Фaйл Richter__2008_02_16.rar являeтcя тeкcтoвoй html cтpaницeй. Xoтитe
coxpaнить этoт фaйл c pacшиpeниeм ".htm" (Richter__2008_02_16.rar.htm)?

А BitComet качает...
Чудеса, не пойму в чем дело, пойду спрошу у кого-нибудь.
Автор: Cyril Konst
Дата сообщения: 07.05.2008 08:03
Есть сложная задача.
При подключении через терминал автоматом создаётся клиентский принтер. При отключении от терминала, он автоматом удаляется. Нужно программку, которая отслеживает создание принтера и назначает права доступа к нему.
Нашёл, что для первой части нужно использовать FindFirstPrinterChangeNotification (FindNextPrinterChangeNotification) с параметром pdwChange == PRINTER_CHANGE_ADD_PRINTER
А по второй части задачи даже чо-то не знаю...
Автор: koderr
Дата сообщения: 08.05.2008 04:21
Здравствуйте.
Проблема такая - нужно научиться делать ReportEvent в custom event log (Event log - это "Приложение", "Безопасность", "Система" в "Просмотре событий"; так вот, нужно создать отдельный журнал). И как минимум, научиться создавать этот custom event log. В MSDN нашел статью How to: Create and Remove Custom Event Logs, но примеры кода, к сожалению, только для VB, C# и J#.
Никто не реализовывал подобное на C? Не поделитесь опытом?

Добавлено:
Попробовал создать вручную соответствующие ветви в реестре - получилось, все пишется, даже не пришлось менять код. Интересно, есть ли какое-то стандартное решение?
Автор: RedPromo
Дата сообщения: 08.05.2008 09:50
koderr
Посмотри в SDK раздел Debugging and Error Handling\Event loging\Event Logging Reference
Функции

Код:
BackupEventLog Saves the specified event log to a backup file.
ClearEventLog Clears the specified event log, and optionally saves the current copy of the log to a backup file.
CloseEventLog Closes a read handle to the specified event log.
DeregisterEventSource Closes a write handle to the specified event log.
GetEventLogInformation Retrieves information about the specified event log.
GetNumberOfEventLogRecords Retrieves the number of records in the specified event log.
GetOldestEventLogRecord Retrieves the absolute record number of the oldest record in the specified event log.
NotifyChangeEventLog Enables an application to receive notification when an event is written to the specified event log.
OpenBackupEventLog Opens a handle to a backup event log.
OpenEventLog Opens a handle to the specified event log.
ReadEventLog Reads a whole number of entries from the specified event log.
RegisterEventSource Retrieves a registered handle to the specified event log.
ReportEvent Writes an entry at the end of the specified event log.
Автор: Cyril Konst
Дата сообщения: 12.05.2008 08:52
RedPromo
Спасибо, а по FindFirstPrinterChangeNotification/FindNextPrinterChangeNotification вам пример не попадался?
Автор: RedPromo
Дата сообщения: 12.05.2008 12:30
Cyril Konst
Как всегда поиск рулит, а вобще я бы с MSDN начал.

Цитата:
Программа, следящая за состоянием очереди принтера. Была написана исключительно для того, что бы понять, как работает функция FindFirstPrinterChangeNotification и еЈ друзья. Может быть полезной для этой же цели. Для простоты использует функцию GetDefaultPrinter, доступную только в Windows 2000 и Windows XP. Избавиться от этой функции не проблема, просто мне это было не нужно да и лень.. Здесь. Весит 10 Кб.

Взято с Ссылка
Автор: Cyril Konst
Дата сообщения: 12.05.2008 13:28
RedPromo
К сожалению, пример не подходит. Т.к. там работа с очередью с существующими принтерами. А мне нужно перехватывать создание нового принтера. И ещё там на С++, а мне нужно на Си и желательно попроще.
Автор: RedPromo
Дата сообщения: 12.05.2008 16:34
Cyril Konst
Тогда извини больше примеров не знаю, тем более на чтобы все на чистом Си.
Но еще раз повторю смотрел MSDN там вроде все нормально описано как и куда.

Как я понял там всеголиш нужно
OpenPrinter(
LPTSTR pPrinterName, // printer or server name
Windows NT/2000/XP: If NULL, it indicates the local printer server.
И потом для локального компа отлавливать установку новых драйверов.
И потом уже както handle принтера получать после установки в системе.

Автор: Cyril Konst
Дата сообщения: 13.05.2008 08:18
RedPromo

Цитата:
Как я понял там всеголиш нужно
OpenPrinter(
LPTSTR pPrinterName, // printer or server name
Windows NT/2000/XP: If NULL, it indicates the local printer server.
И потом для локального компа отлавливать установку новых драйверов.
И потом уже както handle принтера получать после установки в системе.

Принтер создаётся автоматически при логоне терминального юзера. Поэтому у нас в системе, как я понимаю, должна висеть прога с FindFirstPrinterChangeNotification/FindNextPrinterChangeNotification. Она должна отлавливать новый принтер и передавать его имя следующей процедуре SetPrinter для установки прав.
Кстати, когда создаётся новый принтер, соответсвующее предупреждение (с кодом ID : 2) появляется в системном журнале.
Автор: RedPromo
Дата сообщения: 13.05.2008 12:58
Cyril Konst
Дело в том что мне кажется нужно прогу подгружать именно как сервис с правами админа чтобы он стартовал в логон сесии нового юзвера и назначал права кому нужно и как нужно.

Страницы: 12345678910111213141516171819202122232425262728293031323334353637

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


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