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

» C++ WinAPI

Автор: general29
Дата сообщения: 19.10.2007 23:00
Abs62
WM_KILLFOCUS - вроде и оно. но мне хотелось бы написать прогу, которая бы всегда было бы активным, т.е. никогда не теряло бы фокус. Вроде оно, но походу надо бы еще знать ф-ию, что то типа "найти фокус"
Автор: Abs62
Дата сообщения: 19.10.2007 23:27
general29
GetForegroundWindow. Можно ещё посмотреть на LockSetForegroundWindow.
Автор: general29
Дата сообщения: 19.10.2007 23:35
Abs62
не пойму: GetForegroundWindow - эффекту ноль, LockSetForegroundWindow - undeclared (#include <windows.h>). Если не сложно напиши обработку сообщения WM_KILLFOCUS, чтобы окно всегда было активно
Автор: Abs62
Дата сообщения: 19.10.2007 23:58
general29

Цитата:
LockSetForegroundWindow - undeclared

Minimum operating systems: Windows Me, Windows 2000. Какие ОС и компилятор?
Вызывать её надо не в обработчике WM_KILLFOCUS, а в тот момент, когда надо запретить переключение на другие окна. В самом обработчике с окнами особо не поработаешь - "While processing this message, do not make any function calls that display or activate a window. This causes the thread to yield control and can cause the application to stop responding to messages".

Цитата:
GetForegroundWindow - эффекту ноль

А какой должен быть эффект? Эта функция возвращает хэндл текущего активного окна. А WM_KILLFOCUS посылается перед переключением на другое окно, пока фокус ещё не переключён.
Автор: general29
Дата сообщения: 20.10.2007 00:28
Abs62
Windows XP SP2, VC++ 6.0
Автор: Abs62
Дата сообщения: 20.10.2007 01:00
Abs62

Цитата:
VC++ 6.0

По идее должно быть... Скачай Platform SDK с microsoft.com - там точно есть.
Автор: general29
Дата сообщения: 20.10.2007 08:55
Abs62

Цитата:
Скачай Platform SDK с microsoft.com

342 метра - для меня нереально
Автор: Abs62
Дата сообщения: 20.10.2007 11:13
general29
Плохо - такие вещи Win-программисту нужны.
Тогда ручками - через LoadLibrary и GetProcAddress. LockSetForegroundWindow сидит в User32.dll.
Автор: general29
Дата сообщения: 20.10.2007 14:34
Abs62
Спасибо за помощь.
Вообще я только начал изучать WinAPI, так что в скором будущем может и сделаю, что задумал..
Автор: Abs62
Дата сообщения: 20.10.2007 20:14
general29
Действуй. Зная WinAPI, ты сто очков дашь вперёд "программистам", которых отсутствие понятия "форма" повергает в ступор.
Автор: pit23
Дата сообщения: 25.10.2007 15:05
Хелп!

Нужно программно установить время в винде. Для этого я использую функцию SetLocalTime. Но она работает только под админом, а мне нужно чтобы она работала под учетной записью юзера. Можно ли программно получить право на изменение времени ???
Автор: Qraizer
Дата сообщения: 25.10.2007 16:11
Да, если админ предусмотрел . Вообще, Power Users тоже по дефолту имеют эту привилегию, вроде.
Автор: pit23
Дата сообщения: 25.10.2007 16:27
Qraizer

А что должен предусмотреть админ ? Программно значит никак ?
У меня прога работает под учетной записью, которая входит в группу Users



Автор: Abs62
Дата сообщения: 25.10.2007 18:08
pit23

Цитата:
А что должен предусмотреть админ ?

Дать права на изменение системного времени группе "Users", вестимо.

Цитата:
Программно значит никак ?

А какой тогда смысл в разграничении прав, если бы их так просто было бы обойти?
Автор: pit23
Дата сообщения: 26.10.2007 08:17

Цитата:
А какой тогда смысл в разграничении прав, если бы их так просто было бы обойти?


Действительно.

Я просто знаю, что для программного выключения компа нужно получить
право на это действие. Я подумал может и в этом случае как-то это возможно сделать.

Ну ладно все равно спасибо за помощь.

А если запустить прогу от имени администратора, то получиться поменять время?
Автор: Abs62
Дата сообщения: 26.10.2007 08:42
pit23

Цитата:
А если запустить прогу от имени администратора, то получиться поменять время?

Должно. Если администратор сам себе это не запретил, вестимо.
Автор: fox234
Дата сообщения: 21.11.2007 18:24
Всем добрый вечер.

У меня вот такой вопрос, при решении проблемы с мерцанием стандартных контролов винды, я пришел только к одному решению, сабклассить нужные контролы (перехватывая WM_PAINT) и рисовать их в контекст памяти. Но мне кажется, что это не последний выход. Для этого мне надо выводить и графику окна и графику контролов в один контекст памяти. Но как мне это сделать, ведь контролы рисуются всегда с точки (х = 0, у = 0). Если ли способ сабклассить только один раз?
Автор: Abs62
Дата сообщения: 21.11.2007 19:12
fox234

Цитата:
Для этого мне надо выводить и графику окна и графику контролов в один контекст памяти.

To force a window to draw into a specific device context, use the WM_PRINT or WM_PRINTCLIENT message. Note that this requires the target window to support the WM_PRINTCLIENT message. Most common controls support the WM_PRINTCLIENT message. (C) MSDN
Автор: fox234
Дата сообщения: 22.11.2007 22:24
Abs62
Спасибо за подсказку, к стате где-то я уже про это читал.
Если не трудно, кинь часть сырца или посмотри что я делаю не так:

Код:
LONG WINAPI MainWindowProcedure    (
                                    HWND    m_MainWindow,
                                    UINT    Message,
                                    WPARAM    wParam,
                                    LPARAM    lParam
                                )
{
    PAINTSTRUCT    ps;
    HDC            hdc;
    HDC            hdc2;
    POINT        pt1;

    switch (Message)
    {
        case WM_CREATE:
            break;
        case WM_COMMAND:
            break;
        case WM_SIZE:
            break;
        case WM_ERASEBKGND:
        {
            return TRUE;
            break;
        }
        case WM_PAINT:
        {
            hdc = BeginPaint (m_MainWindow, &ps);
            PatBlt(memDC,0,0,m_RC.right-m_RC.left, m_RC.bottom-m_RC.top, BLACKNESS/*PATCOPY*/);

            SendMessage(m_MainWindow, WM_PRINTCLIENT, (WPARAM)memDC, (LPARAM)(PRF_CLIENT | PRF_ERASEBKGND | PRF_CHILDREN));

            GetClientRect(m_MainWindow, &m_RC);
            BitBlt(hdc, 0, 0, m_RC.right-m_RC.left, m_RC.bottom-m_RC.top, memDC, 0, 0, SRCCOPY);
            EndPaint (m_MainWindow, &ps);
            return true;
        }
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc    (
                                        m_MainWindow,
                                        Message,
                                        wParam,
                                        lParam
                                    );
}
return 0;
}
LONG WINAPI SubClassProcedure    (
                                    HWND    Window,
                                    UINT    Message,
                                    WPARAM    wParam,
                                    LPARAM    lParam
                                )
{
    PAINTSTRUCT    ps;
    HDC            hdc;

    if(Message == WM_PRINTCLIENT)
    {
        CallWindowProc(oldControlProc, Window, WM_PAINT, wParam, lParam);
        return 0;
    }
    if(Message == WM_PAINT)
    {
        hdc = BeginPaint (Window, &ps);
        EndPaint (Window, &ps);
        return true;
    }
    if(Message == WM_ERASEBKGND)
    {
        return true;
    }
    return    CallWindowProc    (
                                oldControlProc,
                                Window,
                                Message,
                                wParam,
                                lParam
                            );
}
Автор: Abs62
Дата сообщения: 22.11.2007 23:12
fox234

Цитата:
Если не трудно, кинь часть сырца или посмотри что я делаю не так:

У меня нет такого сырца, я из MSDN цитировал.

Цитата:
SendMessage(m_MainWindow, WM_PRINTCLIENT, (WPARAM)memDC, (LPARAM)(PRF_CLIENT | PRF_ERASEBKGND | PRF_CHILDREN));

Непонятный вызов. Зачем оконная процедура вызывает саму себя таким образом, если она всё равно не обрабатывает WM_PRINTCLIENT?
Полагаю, вместо этого надо пробежаться по контролам с помощью EnumChildWindows, посылая каждому из них WM_PRINTCLIENT с memDC в WPARAM. MSDN уверяет, что стандартные контролы это сообщение отрабатывают.

Цитата:
if(Message == WM_PRINTCLIENT)
{
CallWindowProc(oldControlProc, Window, WM_PAINT, wParam, lParam);
return 0;
}

Я бы для начала попробовал оставить WM_PRINTCLIENT на откуп штатному обработчику.
Автор: diaz85
Дата сообщения: 23.11.2007 15:29
добрый вечер.

вопрос относительно api функции LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam):
как получить дескриптор именно нужного окна? в моем случае это главная форма проекта. заранее спаибо.
Автор: fox234
Дата сообщения: 23.11.2007 15:55
Abs62
Что то я здесь опять запарол. Низлежащий код работает, но не доконца. Контрол рисуется в начале координат хоть и должен рисоватся в нужном месте.

Код:
//---------------------------------------------------------------------------------------------------------------------------
LONG WINAPI MainWindowProcedure    (
                                    HWND    Window,
                                    UINT    Message,
                                    WPARAM    wParam,
                                    LPARAM    lParam
                                )
{
    RECT        RC1;
    PAINTSTRUCT    ps;
    HDC            hdc;

    switch (Message)
    {
        case WM_CREATE:
        {
            self_TabSheet = CreateWindow    (
                                                "SysTabControl32",
                                                "",
                                                WS_CHILD|WS_VISIBLE,
                                                0, 0, 0, 0,
                                                Window,
                                                (HMENU)0,
                                                m_hInstance,
                                                NULL
                                            );
            SendMessage(self_TabSheet, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(true, 0));
            TabItem.mask = TCIF_TEXT|TCIF_PARAM;    
            TabItem.dwState = 0;
            TabItem.dwStateMask = 0;
            TabItem.pszText = "Система";
            TabItem.cchTextMax = 10;
            TabItem.iImage = 0;
            TabItem.lParam = (LPARAM)0;
            SendMessage(self_TabSheet, TCM_INSERTITEM, 1, (LPARAM)&TabItem);
            TabItem.mask = TCIF_TEXT|TCIF_PARAM;    
            TabItem.dwState = 0;
            TabItem.dwStateMask = 0;
            TabItem.pszText = "Система";
            TabItem.cchTextMax = 10;
            TabItem.iImage = 0;
            TabItem.lParam = (LPARAM)0;
            SendMessage(self_TabSheet, TCM_INSERTITEM, 2, (LPARAM)&TabItem);
            SetWindowLong(self_TabSheet, GWL_WNDPROC, (long)&SubTabControlProc);
            return 0;
        }
        case WM_PAINT:
        {
            GetClientRect(Window, &RC1);
            hdc = BeginPaint (Window, &ps);
            PatBlt(memDC,0,0,RC1.right-RC1.left, RC1.bottom-RC1.top, PATCOPY);
            EnumChildWindows(Window, &DrawControlsProc, 0);
            BitBlt(hdc, 0, 0, RC1.right-RC1.left, RC1.bottom-RC1.top, memDC, 0, 0, SRCCOPY);
            EndPaint (Window, &ps);
            return 0;
        }
        case WM_ERASEBKGND:
        {
            return 1;
        }
        case WM_SIZE:
        {
            GetClientRect(Window, &RC1);
            MoveWindow(self_TabSheet, RC1.left+10, RC1.top+10, RC1.right-20, RC1.bottom-20, true);
            return 0;
        }
        case WM_DESTROY:
        {
            PostQuitMessage(0);
            return 0;
        }
    }
    return DefWindowProc    (
                                Window,
                                Message,
                                wParam,
                                lParam
                            );
}
//---------------------------------------------------------------------------------------------------
LONG WINAPI SubTabControlProc    (
                                    HWND    Window,
                                    UINT    Message,
                                    WPARAM    wParam,
                                    LPARAM    lParam
                                )
{
    HDC            hdc;
    PAINTSTRUCT    ps;

    switch (Message)
    {
        case WM_PAINT://Выключаем перерисовку без двойной буферизации
        {
            hdc = BeginPaint (Window, &ps);
            EndPaint (Window, &ps);
            return 0;
        }
    }
    return CallWindowProc    (
                                oldTabControlProc,
                                Window,
                                Message,
                                wParam,
                                lParam
                            );
}
//---------------------------------------------------------------------------------
BOOL CALLBACK DrawControlsProc(HWND hwnd, LPARAM lParam)
{
    SendMessage(hwnd, WM_PRINT, (WPARAM)memDC, (LPARAM)(PRF_CLIENT|PRF_CHILDREN));
    return true;
}
//--------------------------------------------------------------------------------------------
Автор: Abs62
Дата сообщения: 23.11.2007 17:29
diaz85

Цитата:
как получить дескриптор именно нужного окна?

Объясни как именно это самое нужное окно соответствует WindowProc твоего главного окна - там и поговорим.
fox234

Цитата:
хоть и должен рисоватся в нужном месте

Родительское окно - GetParent, детские ты создаёшь сам, и уж будь любезен заботиться о них и следить за ними.

Цитата:
self_TabSheet = CreateWindow (
"SysTabControl32",
"",
WS_CHILD|WS_VISIBLE,
0, 0, 0, 0,
Window,
(HMENU)0,
m_hInstance,
NULL

Ну так где же тут нужное место? Создавая окно, ты задал ему начальные координаты 0, 0 и такие же размеры. Что после этого ты хочешь получить?
Автор: fox234
Дата сообщения: 23.11.2007 21:53
Abs62
Ура, вроде сделал:

Код:
//---------------------------------------------------------------------------------------------------------------------------
LONG WINAPI MainWindowProcedure (
HWND Window,
UINT Message,
WPARAM wParam,
LPARAM lParam
)
{
RECT RC1;
PAINTSTRUCT ps;
HDC hdc;

switch (Message)
{
case WM_CREATE:
{
//-----------------------------------
t1 = GetSystemMetrics(SM_CYCAPTION);
t2 = GetSystemMetrics(SM_CXSIZEFRAME);
t3 = GetSystemMetrics(SM_CYSIZEFRAME);
//-----------------------------------
self_TabSheet = CreateWindow (
"SysTabControl32",
"",
WS_CHILD|WS_VISIBLE,
0, 0, 0, 0,
Window,
(HMENU)0,
m_hInstance,
NULL
);
SendMessage(self_TabSheet, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(true, 0));
TabItem.mask = TCIF_TEXT|TCIF_PARAM;
TabItem.dwState = 0;
TabItem.dwStateMask = 0;
TabItem.pszText = "Система";
TabItem.cchTextMax = 10;
TabItem.iImage = 0;
TabItem.lParam = (LPARAM)0;
SendMessage(self_TabSheet, TCM_INSERTITEM, 1, (LPARAM)&TabItem);
TabItem.mask = TCIF_TEXT|TCIF_PARAM;
TabItem.dwState = 0;
TabItem.dwStateMask = 0;
TabItem.pszText = "Система";
TabItem.cchTextMax = 10;
TabItem.iImage = 0;
TabItem.lParam = (LPARAM)0;
SendMessage(self_TabSheet, TCM_INSERTITEM, 2, (LPARAM)&TabItem);
SetWindowLong(self_TabSheet, GWL_WNDPROC, (long)&SubTabControlProc);
return 0;
}
case WM_PAINT:
{
GetClientRect(Window, &RC1);
hdc = BeginPaint (Window, &ps);
PatBlt(memDC,t2,t1+t2,RC1.right-RC1.left, RC1.bottom-RC1.top, PATCOPY);
//-----------
SendMessage(Window, WM_PRINT, (WPARAM)memDC, (LPARAM)(PRF_CLIENT|PRF_CHILDREN|PRF_CHECKVISIBLE|PRF_ERASEBKGND|PRF_OWNED));
//-----
BitBlt(hdc, 0, 0, RC1.right-RC1.left, RC1.bottom-RC1.top, memDC, t2, t1+t2, SRCCOPY);
EndPaint (Window, &ps);
return 0;
}
case WM_ERASEBKGND:
{
return 1;
}
case WM_SIZE:
{
GetClientRect(Window, &RC1);
MoveWindow(self_TabSheet, RC1.left+10, RC1.top+10, RC1.right-20, RC1.bottom-20, true);
return 0;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc (
Window,
Message,
wParam,
lParam
);
}
//---------------------------------------------------------------------------------------------------
LONG WINAPI SubTabControlProc (
HWND Window,
UINT Message,
WPARAM wParam,
LPARAM lParam
)
{
HDC hdc;
PAINTSTRUCT ps;

HWND pWnd = GetParent(Window);
switch (Message)
{
case WM_PAINT://Выключаем перерисовку без двойной буферизации
{
InvalidateRect(pWnd, NULL, true);
hdc = BeginPaint (Window, &ps);
EndPaint (Window, &ps);
return 0;
}
}
return CallWindowProc (
oldTabControlProc,
Window,
Message,
wParam,
lParam
);
}
//---------------------------------------------------------------------------------
Автор: Abs62
Дата сообщения: 24.11.2007 00:49
fox234
Чессс-говоря, лень проверять. Смотри сам: правильно или нет - смотри по факту. Если действия программы соответствует заданию - правильно, если нет - кочевряжься дальше.
Да, на всякий случ1ай:

Цитата:
For some common controls, the default WM_PAINT message processing checks the wParam parameter. If wParam is non-NULL, the control assumes that the value is an HDC and paints using that device context.

Мало ли понадобится.
Автор: Dmitro25
Дата сообщения: 03.12.2007 11:30
Всем привет!
Пишу собственный аналог инспектора объектов. Для реализации мне понадобилось создать аналог ComboBox'a. Проблема с выпадающим списком (аналог системного ComboLBox). Он реализован с использованием CreateWindow('ComboLBox', ..., организацией собственного цикла обработки сообщений и т.д. Для отслеживания кликов мыши вне области окна приходится делать SetCapture (впрочем, так сделано и в системном ComboLBox). Но! В этом случае не работает прокрутка (ScrollBar) внутри моего окна. В смысле полоса прокрутки появляется когда надо, но при клике мыши на ней перемещение ползунка не происходит. Как это победить?
Привожу пример кода (сорри, что на Delphi, но пример, мне кажется, понятен):

Код:
var
hlb: THandle;
OldWndProc: Pointer;

function ComboLBoxWindowProc(Wnd: HWND; Msg, wParam, lParam: Longint): Longint; stdcall;
begin
Result:=CallWindowProc(OldWndProc, wnd, Msg, wParam, lParam);
case Msg of
WM_LBUTTONDOWN:
begin
ReleaseCapture;
ShowWindow(hlb, SW_HIDE);
end;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
hlb:=CreateWindowEx(WS_EX_TOPMOST or WS_EX_TOOLWINDOW ,
'ComboLBox', '',
WS_CHILD or WS_CLIPSIBLINGS or WS_BORDER or WS_VSCROLL or WS_VISIBLE,
100, 100, 100, 200, handle, 0, HInstance, nil);
windows.SetParent(hlb, 0);
OldWndProc:=Pointer(GetWindowLong(hlb, GWL_WNDPROC));
SetWindowLong(hlb, GWL_WNDPROC, integer(@ComboLBoxWindowProc));

for i:=1 to 20 do
SendMessage(hlb, LB_ADDSTRING, 0, integer(pchar('12345')));
SetCapture(hlb);
end;
Автор: Abs62
Дата сообщения: 03.12.2007 19:37
Dmitro25
Думаю, надо проверять, произошло ли событие мыши над окном полосы прокрутки, и если да - передать его туда на обработку через SendMessage.
Автор: Dmitro25
Дата сообщения: 04.12.2007 06:24
Abs62
Извини, не понял, куда передать? Ведь обработчик оконых сообщений и так мною перекрыт.
Автор: Abs62
Дата сообщения: 04.12.2007 08:02
Dmitro25
Перекрыт обработчик окна комбобокса. А полоса прокрутки - это тоже окно, со своим обработчиком. И если оно не получит сообщение от мыши (а оно и не получит, если мышь захвачена - все сообщения пойдут захватившему её окну), естественно, оно на щелчки и не будет реагировать. Посмотри в сторону ChildWindowFromPoint.
Автор: VictorMi
Дата сообщения: 18.03.2008 19:25
Простая задача - по нажатию кнопки взять текст из окна и запихнуть в Clipboard.
Работает через раз. Похоже что-то не так с GlobalUnlock, но не могу понять

Подскажите пожалуйста

Вот фрагмент
case IDW_BUT_ST1:
{
GetWindowText(hEDI_STR,s000,MAX_STR_LEN-1);
if(SendMessage(hCHB_SAVE_CLIP,BM_GETCHECK,0,0)==BST_CHECKED)
{
HGLOBAL hgl=GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE ,20000);
if(hgl==NULL) break;
LPSTR s4=(LPSTR)GlobalLock(hgl);
strcpy(s4,s000);
int a1=OpenClipboard(hWnd);
int a2=EmptyClipboard();
HANDLE hc=SetClipboardData(CF_TEXT,hgl);
int a3=GlobalUnlock(hgl);
DWORD a4=GetLastError();
HGLOBAL a5=GlobalFree(hgl);
int a6=CloseClipboard();
}

}
break;


Abs62 БОЛЬШОЕ СПАСИБО! Начинаю понимать

Страницы: 12345678910111213141516171819202122232425262728293031323334353637

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


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