Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Блокировка всплывающего меню / 13 сообщений из 13, страница 1 из 1
27.02.2007, 23:06
    #34359086
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка всплывающего меню
нужно сделать сабж для простого edit'a в win32 проекте, какое сообщение отлавливать ума не приложу?

please help

спасибо
--------------------------------------------------------------
[подпись с другого сайта]
...
Рейтинг: 0 / 0
28.02.2007, 21:15
    #34361889
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка всплывающего меню
up

--------------------------------------------------------------
[подпись с другого сайта]
...
Рейтинг: 0 / 0
01.03.2007, 17:43
    #34364598
vanoman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка всплывающего меню
Возможно
WM_RBUTTONDOWN
ON_WM_RBUTTONDOWN()
...
Рейтинг: 0 / 0
01.03.2007, 17:48
    #34364617
vanoman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка всплывающего меню
Хотя ещё один метод вызова меню остётся - спец клавиша на Правлильных клавиатурах. Та что рядом с VK_LWIN, VK_RWIN.
Но её пожно отловить по НАЖАТИЕ КЛАВИШИ...
...
Рейтинг: 0 / 0
01.03.2007, 22:11
    #34365100
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка всплывающего меню
эти сообщения можно разруливать когда у вас есть класс производный от CEdit (у меня есть такой опыт), я же работаю с Win32API
--------------------------------------------------------------
[подпись с другого сайта]
...
Рейтинг: 0 / 0
05.03.2007, 09:26
    #34370329
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка всплывающего меню
решил разрулить проблему с помощью subclassing'a так как описано в MSDN в статье Safe Subclassing In Win32, окно создается но обработка сообщений идет почему-то мимо нужного "обработчика"

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
FARPROC  lpfnOldWndProc;

HWND m_MainDlg = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DLG_MCLIENT), NULL, WndProc);
if(m_MainDlg == NULL)
{/*error*/}

HWND hText = CreateWindow("edit", "", WS_CHILD | WS_VISIBLE | WS_BORDER,  0 ,  0 ,  50 ,  50 , 
					  m_MainDlg, NULL, hInstance, NULL);
//- подменяем обработчик сообщений для edit'a, возвращает не 0
lpfnOldWndProc = (FARPROC) SetClassLong(hText, GCL_WNDPROC, (DWORD) EditWndProc);
//-------------------------------------------------------------------- поставим в трей значок
MSG	msg;
while(GetMessage(&msg, NULL,  0 ,  0 ))
{
	TranslateMessage(&msg);
	DispatchMessage(&msg);
}
SetClassLong(hText, GWL_WNDPROC, (DWORD)lpfnOldWndProc);
DestroyWindow(hText);
...

LRESULT FAR CALLBACK EditWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
//- сюда ввобще не попадает !!!!!
	switch(uMsg)
	{	
		case WM_RBUTTONDOWN:
			MessageBox(NULL, "WM_RBUTTONDOWN", "", NULL);
		break;
	}
	return CallWindowProc((WNDPROC)lpfnOldWndProc, hWnd, uMsg, wParam, lParam);
}

?
--------------------------------------------------------------
[подпись с другого сайта]
...
Рейтинг: 0 / 0
05.03.2007, 14:27
    #34371486
ErV
ErV
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка всплывающего меню
Cerebrumрешил разрулить проблему с помощью subclassing'a так как описано в MSDN в статье Safe Subclassing In Win32, окно создается но обработка сообщений идет почему-то мимо нужного "обработчика"

Код: plaintext
1.
2.
SetClassLong(hText, GWL_WNDPROC, (DWORD)lpfnOldWndProc);
DestroyWindow(hText);

?
--------------------------------------------------------------
[подпись с другого сайта]
В справке сказано:

Calling SetClassLong with the GCL_WNDPROC index creates a subclass of the window class that affects all windows subsequently created with the class. An application can subclass a system class, but should not subclass a window class created by another process.

Т.е. как я понял - влияет на окна, созданные ПОСЛЕ вызова SetClassLong...
...
Рейтинг: 0 / 0
05.03.2007, 15:44
    #34371776
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка всплывающего меню
Привет!
глянь еще раз на пример в справке, точнее на очередность вызыва SetClassLong
там требуется хэндл только что созданного окна!
--------------------------------------------------------------
[подпись с другого сайта]
...
Рейтинг: 0 / 0
05.03.2007, 16:47
    #34371995
ErV
ErV
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка всплывающего меню
CerebrumПривет!

Привет, рад "слышать" :).
Cerebrum
глянь еще раз на пример в справке, точнее на очередность вызыва SetClassLong
там требуется хэндл только что созданного окна!
--------------------------------------------------------------
[подпись с другого сайта]
Ещё там сказано, что префикс не GWL_ а GCL_

DWORD SetClassLong( HWND hWnd,
int nIndex,
LONG dwNewLong
);

...


GCL_WNDPROC
Replaces the address of the window procedure associated with the class.

Лично у меня GWL_WNDPROC == -4, а GCL_WNDPROC == -24 ;... :)
Может, потому и не пашет?
ЗЫ. Ещё рекомендуют SetClassLongPtr дабы обеспечить совместимость с x64 версиями.
...
Рейтинг: 0 / 0
05.03.2007, 17:06
    #34372062
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка всплывающего меню
GWL_ - это instance subclassing
GCL_ - это global subclassing
один черт ни так ни сяк не работает

видимо придеться хучить...
--------------------------------------------------------------
[подпись с другого сайта]
...
Рейтинг: 0 / 0
05.03.2007, 22:28
    #34372731
ErV
ErV
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка всплывающего меню
CerebrumGWL_ - это instance subclassing
GCL_ - это global subclassing
один черт ни так ни сяк не работает

видимо придеться хучить...
--------------------------------------------------------------
[подпись с другого сайта]
Отлично сабклассинг работает. Только там есть одна интересная вещь.
В случае ошибки, вместо старой процедуры возвращается ноль.
Что конкретно случилось, можно узнать, сделав, например, вот так:
Код: plaintext
1.
2.
3.
4.
5.
6.
DWORD err = GetLastError();
	if (err){
		char buf[ 1024 ];
		FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,  0 , err,  0 , buf,  1024 ,  0 );
		MessageBoxA( 0 , buf, "Caption", MB_OK|MB_SETFOREGROUND);
	}
Так, например, при попытке вызова SetWindowLong с параметром GCL_WNDPROC возвращает сообщение "неверный индекс".

В случае с SetClassLong процедура все-таки (опытным путем проверил) меняется для всех окон созаднных ПОСЛЕ вызова SetClassLong. Т.е. для окна, переданного в SetClassLong оконная процедура не меняется. Её нужно менять при помощи SetWindowLong(..GWL_WNDPROC..)


Вот рабочий листинг программы с использованием SetClassLong:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
#include <windows.h>

#define WNDCLASSNAME TEXT("WinMin")
#define WNDCAPTION TEXT("WinMin")

static bool g_bRunning = true;

LRESULT WINAPI WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam){
	switch(Msg){
		case (WM_DESTROY):{
			g_bRunning = false;
			PostQuitMessage( 0 );
			return  0 ;
		}
        default:
            return DefWindowProc(hWnd, Msg, wParam, lParam);
	}
}

WNDPROC oldFunc =  0 ;
LRESULT WINAPI subClassFunc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam){
	if (Msg == WM_RBUTTONDOWN)
		MessageBox ( 0 , TEXT("WM_RBUTTONDOWN"), TEXT("info"), MB_OK|MB_SETFOREGROUND);
	return CallWindowProc(oldFunc, hWnd, Msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, int){
    WNDCLASS wc = {
        CS_VREDRAW|CS_HREDRAW,
        WndProc,  0 ,  0 ,
        hInst,
        LoadIcon( 0 , IDI_APPLICATION),
        LoadCursor( 0 , IDC_ARROW),
        (HBRUSH)GetStockObject(LTGRAY_BRUSH),
         0 ,
        WNDCLASSNAME
    };

    RegisterClass(&wc);

    HWND hWnd = 
    CreateWindow(
                                WNDCLASSNAME,
                                WNDCAPTION, 
                                WS_OVERLAPPEDWINDOW,
                                CW_USEDEFAULT,
                                CW_USEDEFAULT,
                                CW_USEDEFAULT,
                                CW_USEDEFAULT,
                                 0 ,  0 , hInst,  0 
                                );

	HWND hEditWnd = CreateWindow(TEXT("EDIT"), TEXT("Edit test"), WS_CHILD|ES_LEFT|WS_BORDER/*|WS_VISIBLE*/,  0 ,  0 ,  150 ,  30 , hWnd,  0 , hInst,  0 );
	//oldFunc = (WNDPROC) SetWindowLong(hEditWnd, GWL_WNDPROC, (DWORD)&subClassFunc);
	oldFunc = (WNDPROC) SetClassLong(hEditWnd, GCL_WNDPROC, (DWORD)&subClassFunc);
	DestroyWindow(hEditWnd);
	hEditWnd = CreateWindow(TEXT("EDIT"), TEXT("Edit test"), WS_CHILD|ES_LEFT|WS_BORDER/*|WS_VISIBLE*/,  0 ,  0 ,  150 ,  30 , hWnd,  0 , hInst,  0 );
	
	DWORD err = GetLastError();
	if (err){
		TCHAR buf[ 1024 ];
		FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,  0 , err,  0 , buf,  1024 ,  0 );
		MessageBox( 0 , buf, TEXT("Caption"), MB_OK|MB_SETFOREGROUND);
	}
	ShowWindow(hEditWnd, SW_SHOW);
	
    UpdateWindow(hWnd);
    ShowWindow(hWnd, SW_SHOW);

    MSG msg;
    while (g_bRunning){
        if (PeekMessage(&msg, hWnd,  0 ,  0 , PM_REMOVE)){
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else{
            //idle
        }
    }

    UnregisterClass(WNDCLASSNAME, hInst);

    return  0 ;
}
...
Рейтинг: 0 / 0
05.03.2007, 22:34
    #34372739
ErV
ErV
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка всплывающего меню
Кстати, меню отлично блокируется вот такой оконной процедурой:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
WNDPROC oldFunc =  0 ;
LRESULT WINAPI subClassFunc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam){
	if (Msg == WM_RBUTTONDOWN)
		return  0 ;
	else
		return CallWindowProc(oldFunc, hWnd, Msg, wParam, lParam);
}
...
Рейтинг: 0 / 0
06.03.2007, 08:50
    #34373056
Cerebrum
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Блокировка всплывающего меню
большое спасибо , буду разбираться

--------------------------------------------------------------
[подпись с другого сайта]
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Блокировка всплывающего меню / 13 сообщений из 13, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]