C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
SendMessage, Hide
joynter
Отправлено: 06.12.2004, 10:16


Станционный диспетчер

Группа: Участник
Сообщений: 137



если Form1->Hide(), то можно ли и каким образом передать сообщение Form1?
Konstantine
Отправлено: 06.12.2004, 10:27


Мастер участка

Группа: Модератор
Сообщений: 545



передаёшь как и обычно, но только программно... т.к. внешнего интерфейса нету...
joynter
Отправлено: 06.12.2004, 10:34


Станционный диспетчер

Группа: Участник
Сообщений: 137



QUOTE
передаёшь как и обычно, но только программно

это как? я вроде и так не в ручную
Gedeon
Отправлено: 06.12.2004, 10:48


Ветеран

Группа: Модератор
Сообщений: 1742



Я вообще не пойму в чем вопрос, хэндл есть? Если есть то без разницы видимая форма или нет, передавайте что хотите.
Konstantine
Отправлено: 06.12.2004, 10:53


Мастер участка

Группа: Модератор
Сообщений: 545



ну SendMessage вроде... а что? есть проблемы? напиши что именно нада — какое сообщение и что делать по нему
olegenty
Отправлено: 06.12.2004, 11:55


Ветеран

Группа: Модератор
Сообщений: 2412



да хоть чего бы они ни хотел, а SendMessage/PostMessage по-любому...
joynter
Отправлено: 06.12.2004, 13:44


Станционный диспетчер

Группа: Участник
Сообщений: 137



вот что есть
CODE

/*** ExpImpUtils.h ***/
#ifdef __DLL__
#       define _EXPORT_FLAG_ __declspec(dllexport)
#else
#       define _EXPORT_FLAG_ __declspec(dllimport)
#endif

extern "C" bool _EXPORT_FLAG_ InstHook(HANDLE);
extern "C" bool _EXPORT_FLAG_ UninstHook();

сама форма
CODE

/** Unit.срр **/
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "InvisibleUnit1.h"
#include "ExpImpUtils.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
HINSTANCE hDll;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
       : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
Hide();        
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
hDll = LoadLibrary("kbd.dll");
if(hDll)
 {
 Inst *inst = (Inst*)GetProcAddress(hDll,"_InstHook");
 if(inst) inst(Handle);
 }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
if(hDll)
 {
 Uninst *uninst = (Uninst*)GetProcAddress(hDll,"_UninstHook");
 if(uninst) uninst();
 }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::OnWmUser(TMessage &mes)
{
ShowMessage(mes.LParam);
}


/**** Unit.h ****/
//---------------------------------------------------------------------------

#ifndef InvisibleUnit1H
#define InvisibleUnit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // IDE-managed Components
       void __fastcall FormPaint(TObject *Sender);
       void __fastcall FormCreate(TObject *Sender);
       void __fastcall FormDestroy(TObject *Sender);
private: // User declarations
       typedef bool (__import *Inst(HANDLE));
       typedef bool (__import *Uninst());
       void __fastcall OnWmUser(TMessage &mes);
public:  // User declarations
       __fastcall TForm1(TComponent* Owner);
       BEGIN_MESSAGE_MAP
               MESSAGE_HANDLER(WM_USER,TMessage,OnWmUser)
       END_MESSAGE_MAP(TComponent)
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

либа

CODE

//---------------------------------------------------------------------------
/****** kbd.dll *****/
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#include "ExpImpUtils.h"
HHOOK hHook = NULL;
HINSTANCE hDll = NULL;
HANDLE hDest = NULL;
bool is_KbdHook = false;
LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam);
//******
bool InstHook(HANDLE hwnd)
{
hDest = hwnd;
if(hHook) return false;
hHook = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,hDll,0);
if(hHook) return true;
return false;
}
//******
bool UninstHook()
{
if(hHook)
 if(UnhookWindowsHookEx(hHook)) return true;
return false;
}
//******
LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)
{
if(nCode < 0) return CallNextHookEx(hHook,nCode,wParam,lParam);
if(GetKeyState(VK_CONTROL) && (is_KbdHook == false))
 {
 switch(wParam)
   {
   case VK_UP:
       SendMessage(hDest,WM_USER,0,9);
       break;
   case VK_DOWN:
       SendMessage(hDest,WM_USER,0,1);
       break;
   }
 is_KbdHook = true;
 }
else is_KbdHook = false;
return CallNextHookEx(hHook,nCode,wParam,lParam);
}
//---------------------------------------------------------------------------

#pragma argsused
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fwdreason, LPVOID lpvReserved)
{
       hDll = hinstDLL;
       return 1;
}
//---------------------------------------------------------------------------


когда в ОнПайнте Хайд, то сообщения не приходят, когда не Хайд всё нормально
Konstantine
Отправлено: 06.12.2004, 15:14


Мастер участка

Группа: Модератор
Сообщений: 545



а на кой тебе в онпайнте хайд???
joynter
Отправлено: 06.12.2004, 15:43


Станционный диспетчер

Группа: Участник
Сообщений: 137



а он нигде больше, кроме как в ОнПайнте не работает
Konstantine
Отправлено: 06.12.2004, 16:42


Мастер участка

Группа: Модератор
Сообщений: 545



насколько я понял — тебе надо чтоб форма не отобразилась?
если так, то в файле проекта (типа project1.cpp) перед Run нада установить флаг...
конкретно не помню какой, но найдёшь — Application-> и ищи булевы свойства (property) и из них выбери... это будет типа "автоматически отображать форму"...
joynter
Отправлено: 06.12.2004, 17:07


Станционный диспетчер

Группа: Участник
Сообщений: 137



есть там св-во ShowMainForm, но им, видимо, и управляет метод Hide() — тот же вид с боку.
Konstantine
Отправлено: 06.12.2004, 18:08


Мастер участка

Группа: Модератор
Сообщений: 545



Не, как раз наоборот.
если поставишь в fasle, то твоя форма будет создана и приложение будет работать, но только скрыто.... пока Show никто не пришлёт...
поставь
CODE
Application->ShowMainForm=fаlse;

перед
CODE
Application->Run();

и увидишь...

судя из твоего hide в onpaint это тебе и нада... или ЧТО???
joynter
Отправлено: 06.12.2004, 18:16


Станционный диспетчер

Группа: Участник
Сообщений: 137



пробывал уже.
дело в том, что когда Application->ShowMainForm = false, сообщения не доходят.
а вот, кстати, как послать (именно через SendMessage) те же Hide() и Show()?
timson
Отправлено: 06.12.2004, 20:27


Станционный диспетчер

Группа: Участник
Сообщений: 82



QUOTE
как послать (именно через SendMessage) те же Hide() и Show()
ShowWindow(HWND hWnd, SW_HIDE);
или SW_SHOW

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

вообще Win32 приложение построено так:
WinMain
- регистрация класса окна
- создание окна
здесь в функции окна WndProc сообщение WM_CREATE, т.е. OnCreate)
- потом идет ShowWindow(hWnd)!!! оно то и вызывает OnPaint. вот его то и нада коментировать, но где оно?? вот в чем вопрос, не после него, не до вставка функций не поможет, прорисовка одина раз будет всяко.
- бесконечный цикл сообщений...

кстати хорошая вещь — VCL_MESSAGE_HANDLER, мона много сообщений перехватывать, до их использования классом окна..
joynter
Отправлено: 07.12.2004, 10:29


Станционный диспетчер

Группа: Участник
Сообщений: 137



QUOTE
проблему полностью не понял..

хендл есть, а окна нет — кому будет отправлено сообщение?
timson
Отправлено: 07.12.2004, 11:08


Станционный диспетчер

Группа: Участник
Сообщений: 82



QUOTE
хендл есть, а окна нет — кому будет отправлено сообщение?
как это..
если есть хандл != NULL, то есть окно, которое (обычно) просто невидимо..

если есть хандл, то значит вызвалась функция CreateWindow, которая создала окно, которая в

свою очередь посылает созданному окну сообщение WM_CREATE (OnCreate)..

если OnCreate не приходит, значит окно не создано, и не может быть хендла...

потом тока идет WM_PAINT.


если нада чтобы прога работала в фоне, то зачем окно вообще..
может процесс в трей убрать?? или вообще сервис делать..
joynter
Отправлено: 07.12.2004, 12:34


Станционный диспетчер

Группа: Участник
Сообщений: 137



QUOTE
если нада чтобы прога работала в фоне, то зачем окно вообще..

для этого ей и делается Application->ShowMainForm = false
QUOTE
если есть хандл != NULL, то есть окно, которое (обычно) просто невидимо..

собственно пока его не видно, сообщение передать не могу (см исходник выше)
Konstantine
Отправлено: 07.12.2004, 12:44


Мастер участка

Группа: Модератор
Сообщений: 545



но окно ЕСТЬ!!! даже если скрыто....
joynter
Отправлено: 07.12.2004, 14:54


Станционный диспетчер

Группа: Участник
Сообщений: 137





еще одну фишку заметил:
если
Form1->Caption = "Form1",
то GetWindowText дает Form1,
а если Form1->Caption = "Form1" и Form1->Hide(), то возвращается имя ехе-шника.
timson
Отправлено: 07.12.2004, 19:21


Станционный диспетчер

Группа: Участник
Сообщений: 82



QUOTE
собственно пока его не видно, сообщение передать не могу
значит окно не

создано!!! (или билдер кривой)

для тех кто в танке:
CODE

WNDCLASS wc = { 0 };


wc.style  = CS_HREDRAW | CS_VREDRAW;
...
wc.lpfnWndProc  = (WNDPROC) WindowProc; // функция обработки сообщений окна
wc.lpszClassName = "WndClassT";


hWnd = CreateWindow("WndClassT", "Win32App", ..); // WM_CREATE


ShowWindow(hWnd, nCmdShow); // показать окно, оно то и посылает сообщение WM_PAINT
UpdateWindow(hWnd);


while (GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

вот этот CreateWindow сам посылает окну сообщение WM_CREATE, потом только отрабатывает.

это основа основ создания Win32 прложений.. это нада знать..
joynter
Отправлено: 08.12.2004, 09:35


Станционный диспетчер

Группа: Участник
Сообщений: 137



QUOTE (timson @ 07/12/2004, 20:23)
QUOTE
собственно пока его не видно, сообщение передать не могу
значит окно не

создано!!! (или билдер кривой)


на счет кривизны билдера ничего сказать не могу (тк не имею возможности в этом убедиться на 100%), а вот для проерки на счет не созданного еще окна я кинул на форму кнопку с известной реакцией (т.е. Hide()) — и все теже помидоры : пока формувидно — все работает, жму кнопку — не работает.
Gedeon
Отправлено: 08.12.2004, 12:27


Ветеран

Группа: Модератор
Сообщений: 1742



Так, батенька, давайте по порядку, в отладчике брикпоинты на получение сообщений ставили? Если есть хэндл — окно тоже есть, и соответственно сообщение оно получает, если оно ему отправляется, по поводу мессаджбоксов, так у не видимой формы Вы их и не увидите, создайте функцию в длл, тогда независимо от видимости формы все будет на экране. Чудес как извесно не бывает, пробовали пользоваться spy++ || winsight?
joynter
Отправлено: 08.12.2004, 13:06


Станционный диспетчер

Группа: Участник
Сообщений: 137



QUOTE

в отладчике брикпоинты на получение сообщений ставили?

ставил : форму видно — брекпойнты брекпойнтят, не видно — пролетают.
QUOTE

по поводу мессаджбоксов, так у не видимой формы Вы их и не увидите

если я правильно понимаю, то по Вашему в какой обработчик МессБокс ни поставь, при Хайде и МессБокс будет хайд. Но:
CODE

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
char wt[256];
GetWindowText(Handle,wt,256);
ShowMessage(wt);
}

при любом ТамИнтервале и любой видимости формы МессБокс показывается !!!
QUOTE

пробовали пользоваться spy++ || winsight?

извините, но я — начинающий чайник — не умею пользоваться winsight.
(в winsight вижу изменени только при наведении мыши на кнопки в правом верхнем углу (ессно при видимой форме), а на нажатие клавиш (т.е. на мой хук) он, по-моему, не реагирует)

Отредактировано joynter — 08/12/2004, 14:09
timson
Отправлено: 08.12.2004, 14:57


Станционный диспетчер

Группа: Участник
Сообщений: 82



все, вроде понял в чем вопрос:
- если Form1->Hide(), то сообщения не приходят..
а я то думал, что б убрать первое сообщение о прорисовке.

а вот почему не приходят сообщения:
- когда окно Hide, то оно не активно и не видимо, вследствие стандартные сообщения (клава, мышь, рисование и т.д.) не

доходят. попробуй поставь таймер, от него дойдут, и дойдут которые принудительно отправляются данному окну.

вот и все..
Gedeon
Отправлено: 08.12.2004, 15:07


Ветеран

Группа: Модератор
Сообщений: 1742



Да, с мессагбоксами я погорячился — это происходит если форма свернута с помощью TTrayIcon, ну а по поводу сообщений все работает вот прилагаю два проекта проверяйте.

Да, может потребовать библиотеки к-рые у вас не установлены, удалите их из *.bpr

Отредактировано Gedeon — 08/12/2004, 16:11

User Attached Image Скачать файл
HIDEMESSAGE.zip


joynter
Отправлено: 08.12.2004, 17:03


Станционный диспетчер

Группа: Участник
Сообщений: 137



2Gedeon спасибо за примеры.
ошибка такова : различия в хенле — я хендл передаю как параметр при
установке хука, а у Вас он ищется через ФайндВиндоу.
т.е. получается, что когда передается хендл невидимого окна  — окно меняет хендл?

Вернуться в Вопросы программирования в C++Builder