dllee 站務副站長
    

發表:315
回覆:2470
積分:1695
註冊:2002-04-15
發送簡訊給我
|
 |
|

主要參考及回應:
■【BCB】【問題】拖曳Form的問題
http://delphi.ktop.com.tw/topic.php?TOPIC_ID=55691
主要是因為 TitleBar 在移動時會看不到,不要 TitleBar
使用簡單自定的移動表單模式即可,不想下載可看以下的原始碼。
此工具對我來說,可用於筆記型電腦的使用者,因為筆記型電腦
的鍵盤都把數字鍵盤與其它按鍵結合在一起,而且每一台還都不一樣。
這個小工具預計會加入 StatPlus2系統資源監測器。
在以下的程式中,ImageList 只是為了模擬 [ X ] 按鈕可以像真的一樣,
在移動上去時變亮,移走變暗,如果不要這樣玩,程式可以更簡化一些。
另外,我會把表單預設隱藏在螢幕右邊,要用時再移出,用完就自動隱藏,
這樣就不會占空間。如果想把它移動螢幕左邊,只要按下表單不放,一直
拖到螢幕的左邊即可,如果要移回右邊也是一樣,不過在顯示時,它只會
顯示在最左邊或最右邊喔。
左上角的圖示,其說明文字目前 Active 視窗的 Title 可以讓您確認視窗。
//---------------------------------------------------------------------------
// ScreenKeyBoard (NumberPad) by Dong-Liang Lee http://dllee.ktop.com.tw
// <2004-09-18> 初版,自動隱藏到螢幕左邊或右邊,左上角圖示說明顯示目前
// Active 的視窗名稱。
// 已知 BUG,只能按下數字鍵,不論是否 Number Locked。
// 主要用途:對於使用 NoteBook 的使用者因鍵盤濃縮,NumberPad
// 不易操作,使用此小工具,可以按需要的 NumberPad。
// 未來預計會加到 StatPlus2 之中。
//---------------------------------------------------------------------------
#include
#pragma hdrstop
#include "testKeyboardUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TFormKeyBoard *FormKeyBoard;
bool bMouseInForm;
bool bMouseInXButton;
bool bMouseDown;
int iDownX,iDownY;
bool bStickLeft;
HWND hwndLastActived=0;
//---------------------------------------------------------------------------
__fastcall TFormKeyBoard::TFormKeyBoard(TComponent* Owner) : TForm(Owner)
{ Btn0->Tag=VK_NUMPAD0; Btn1->Tag=VK_NUMPAD1; Btn2->Tag=VK_NUMPAD2; Btn3->Tag=VK_NUMPAD3; Btn4->Tag=VK_NUMPAD4; Btn5->Tag=VK_NUMPAD5; Btn6->Tag=VK_NUMPAD6; Btn7->Tag=VK_NUMPAD7; Btn8->Tag=VK_NUMPAD8; Btn9->Tag=VK_NUMPAD9; BtnPlus->Tag=VK_ADD; BtnMinus->Tag=VK_SUBTRACT; BtnSlash->Tag=VK_DIVIDE; BtnStar->Tag=VK_MULTIPLY; BtnDot->Tag=VK_DECIMAL; BtnNumberLock->Tag=VK_NUMLOCK; BtnEnter->Tag=VK_RETURN; ImageList1->GetBitmap(2,ImgBtnClose->Picture->Bitmap); this->BorderStyle=bsNone; this->Width=103; this->Height=152; bStickLeft=true; bMouseInForm=true; DoubleBuffered=true;
}
//---------------------------------------------------------------------------
void __fastcall TFormKeyBoard::FormCreate(TObject *Sender)
{ // http://delphi.ktop.com.tw/topic.php?TOPIC_ID=55691 long wsex=::GetWindowLongPtr(Handle,GWL_EXSTYLE); wsex |= WS_EX_NOACTIVATE; ::SetWindowLongPtr(Handle,GWL_EXSTYLE,wsex);
}
//---------------------------------------------------------------------------
void __fastcall TFormKeyBoard::BtnClick(TObject *Sender)
{ TButton *Btn=dynamic_cast(Sender); if(Btn==NULL)return; BYTE scancode = (BYTE)MapVirtualKey(Btn->Tag, 0); keybd_event(Btn->Tag,scancode,KEYEVENTF_EXTENDEDKEY|0,0); keybd_event(Btn->Tag,scancode,KEYEVENTF_EXTENDEDKEY|KEYEVENTF_KEYUP,0); ImageList1->GetBitmap(2,ImgBtnClose->Picture->Bitmap); ImgBtnClose->Invalidate(); SetWindowPos(this->Handle,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
}
//---------------------------------------------------------------------------
void __fastcall TFormKeyBoard::FormMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{ bMouseDown=true; iDownX=X; iDownY=Y; SetWindowPos(this->Handle,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
}
//---------------------------------------------------------------------------
void __fastcall TFormKeyBoard::FormMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y)
{ bMouseDown=false;
}
//---------------------------------------------------------------------------
void __fastcall TFormKeyBoard::FormMouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{ if(bMouseInForm==false) { bMouseInForm=true; this->Color=clActiveCaption; if(bStickLeft) this->Left=Screen->Width-this->Width; // Show else this->Left=0; // Show } if(bMouseInXButton==true) { bMouseInXButton=false; ImageList1->GetBitmap(2,ImgBtnClose->Picture->Bitmap); ImgBtnClose->Invalidate(); } if(bMouseDown) { if(bStickLeft) { if(-X>Screen->Width*3/4) { bStickLeft=false; this->Left=0; } } else { if(X>Screen->Width*3/4) { bStickLeft=true; this->Left=Screen->Width-this->Width; } } // this->Left+=X-iDownX; // 因為我只想移動 Y 方向 this->Top+=Y-iDownY; }
}
//---------------------------------------------------------------------------
void __fastcall TFormKeyBoard::ImgBtnCloseClick(TObject *Sender)
{ Close();
}
//---------------------------------------------------------------------------
void __fastcall TFormKeyBoard::ImgBtnCloseMouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{ if(bMouseInForm==false) { bMouseInForm=true; this->Color=clActiveCaption; if(bStickLeft) this->Left=Screen->Width-this->Width; // Show else this->Left=0; // Show } if(bMouseInXButton==false) { bMouseInXButton=true; ImageList1->GetBitmap(1,ImgBtnClose->Picture->Bitmap); ImgBtnClose->Invalidate(); }
}
//---------------------------------------------------------------------------
void __fastcall TFormKeyBoard::Timer1Timer(TObject *Sender)
{ // Try to find the foreground windows // http://delphi.ktop.com.tw/topic.php?TOPIC_ID=37920 再改良一下 HWND hwndThisActived=GetForegroundWindow(); if(hwndLastActived!=hwndThisActived) { if(hwndThisActived==this->Handle) { hwndThisActived=hwndLastActived; if(hwndLastActived!=0) SetForegroundWindow(hwndLastActived); } SetWindowPos(this->Handle,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE); hwndLastActived=hwndThisActived;
char LastActivedTitle[256]; GetWindowText(hwndLastActived,LastActivedTitle,256); this->Image1->Hint=AnsiString(LastActivedTitle); }
if(bMouseDown==false && bMouseInForm==true) { POINT MousePos; if (GetCursorPos(&MousePos)) { if(this->Left > MousePos.x || this->Top > MousePos.y || this->Left+this->Width < MousePos.x || this->Top+this->Height < MousePos.y) { bMouseInForm=false; this->Color=clNavy;//clInactiveCaption; if(bStickLeft) this->Left=Screen->Width-3; // Hide else this->Left=3-this->Width; // Hide if(bMouseInXButton==true) { bMouseInXButton=false; ImageList1->GetBitmap(2,ImgBtnClose->Picture->Bitmap); ImgBtnClose->Invalidate(); } } } }
}
//---------------------------------------------------------------------------
吃軟也吃硬 dllee.ktop.com.tw 視動科技 VMASK - ViewMove Automation Software Kernel |
|
------ http://blog.yam.com/dllee/
|
conundrum 尊榮會員
    

發表:893
回覆:1272
積分:628
註冊:2004-01-06
發送簡訊給我
|
 |
|
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/attachthreadinput.asp
AttachThreadInput
The AttachThreadInput function attaches or detaches the input processing mechanism of one thread to that of another thread.
BOOL AttachThreadInput( DWORD idAttach, DWORD idAttachTo, BOOL fAttach
);
Parameters
idAttach
[in] Identifier of the thread to be attached to another thread. The thread to be attached cannot be a system thread.
idAttachTo
[in] Identifier of the thread to which idAttach will be attached. This thread cannot be a system thread.
A thread cannot attach to itself. Therefore, idAttachTo cannot equal idAttach.
fAttach
[in] If this parameter is TRUE, the two threads are attached. If the parameter is FALSE, the threads are detached.
Return Values
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. There is no extended error information; do not call GetLastError.
Remarks
Windows created in different threads typically process input independently of each other. That is, they have their own input states (focus, active, capture windows, key state, queue status, and so on), and they are not synchronized with the input processing of other threads. By using the AttachThreadInput function, a thread can attach its input processing to another thread. This also allows threads to share their input states, so they can call the SetFocus function to set the keyboard focus to a window of a different thread. This also allows threads to get key-state information. These capabilities are not generally possible.
The AttachThreadInput function fails if either of the specified threads does not have a message queue. The system creates a thread's message queue when the thread makes its first call to one of the USER or GDI functions. The AttachThreadInput function also fails if a journal record hook is installed. Journal record hooks attach all input queues together.
Note that key state, which can be ascertained by calls to the GetKeyState or GetKeyboardState function, is reset after a call to AttachThreadInput. You cannot attach a thread to a thread in another desktop.
Requirements
Client: Requires Windows XP, Windows 2000 Professional, Windows NT Workstation, Windows Me, Windows 98, or Windows 95.
Server: Requires Windows Server 2003, Windows 2000 Server, or Windows NT Server.
Header: Declared in Winuser.h; include Windows.h.
Library: Use User32.lib.
See Also
Processes and Threads Overview, Process and Thread Functions, GetCurrentThreadId, GetKeyState, GetKeyboardState, GetWindowThreadProcessId, SetFocus
報告 dllee 利害 期待
小鍵盤 再現江湖 哈哈
發表人 - conundrum 於 2004/09/21 18:59:30 |
|
|
teddywolf 一般會員


發表:0
回覆:1
積分:0
註冊:2004-09-24
發送簡訊給我
|
 |
|
dlllee的程序在win 2K以上工作正常。
但在win98下會有失去焦點的問題。
在98中你嘗試在資源管理器(繁体WIN中的名字應該是:檔案總管)
中修改文件名,點擊數字鍵盤將使資源管理器失去焦點。
用AttachThreadInput()做的VC的程序也有同樣的問題。
實際上在WIN2K以上的系統,只要添加了屬性WS_EX_NOACTIVATE就可以
解決焦點丟失問題。
但在98下,這個問題該如何解決,有人研究過嗎?
我這里有一個程序是用DELPHI寫的soft_keyboard,可惜沒有源碼,
在WIN98,WIN2K下都可以正常工作。請告訴我如何上傳這個例子。
|
|
|
sanujp00 一般會員


發表:0
回覆:1
積分:0
註冊:2009-03-19
發送簡訊給我
|
 |
|
我把他改成 Delphi ,真的很好用 ============================
unit TestKeyboardUnit; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ImgList, ExtCtrls, StdCtrls; type TFormKeyBoard = class(TForm) Image1: TImage; ImgBtnClose: TImage; BtnNumberLock: TButton; BtnSlash: TButton; BtnStar: TButton; BtnMinus: TButton; Btn9: TButton; BtnPlus: TButton; Btn8: TButton; Btn7: TButton; Btn4: TButton; Btn5: TButton; Btn6: TButton; Btn3: TButton; Btn2: TButton; Btn1: TButton; Btn0: TButton; BtnDot: TButton; BtnEnter: TButton; Timer1: TTimer; ImageList1: TImageList; procedure FormCreate(Sender: TObject); procedure BtnNumberLockClick(Sender: TObject); procedure FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure ImgBtnCloseClick(Sender: TObject); procedure ImgBtnCloseMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure Timer1Timer(Sender: TObject); private { Private declarations } public { Public declarations } end; var FormKeyBoard: TFormKeyBoard; bMouseInForm:Boolean; bMouseInXButton:Boolean; bMouseDown:Boolean; iDownX,iDownY:Integer; bStickLeft:Boolean; hwndLastActived : THandle; implementation {$R *.dfm} procedure TFormKeyBoard.FormCreate(Sender: TObject); var wsex:Longint; begin Btn0.Tag := VK_NUMPAD0; Btn1.Tag := VK_NUMPAD1; Btn2.Tag := VK_NUMPAD2; Btn3.Tag := VK_NUMPAD3; Btn4.Tag := VK_NUMPAD4; Btn5.Tag := VK_NUMPAD5; Btn6.Tag := VK_NUMPAD6; Btn7.Tag := VK_NUMPAD7; Btn8.Tag := VK_NUMPAD8; Btn9.Tag := VK_NUMPAD9; BtnPlus.Tag := VK_ADD; BtnMinus.Tag := VK_SUBTRACT; BtnSlash.Tag := VK_DIVIDE; BtnStar.Tag := VK_MULTIPLY; BtnDot.Tag := VK_DECIMAL; BtnNumberLock.Tag := VK_NUMLOCK; BtnEnter.Tag := VK_RETURN; ImageList1.GetBitmap(2,ImgBtnClose.Picture.Bitmap); self.BorderStyle:=bsNone; // self.Width:=103; // self.Height:=152; bStickLeft:=true; bMouseInForm:=true; DoubleBuffered:=true; //====================================================== // wsex :=GetWindowLongPtr(Self.Handle,GWL_EXSTYLE); wsex :=GetWindowLong(Self.Handle,GWL_EXSTYLE); wsex := wsex OR WS_EX_NOACTIVATE; // SetWindowLongPtr(Self.Handle,GWL_EXSTYLE,wsex); SetWindowLong(Self.Handle,GWL_EXSTYLE,wsex); end;
procedure TFormKeyBoard.BtnNumberLockClick(Sender: TObject); var Btn:TButton; scancode:BYTE; begin Btn:=(Sender as TButton); //dynamic_cast(Sender); if(Btn=NIL) then exit; scancode := BYTE( MapVirtualKey(Btn.Tag, 0) ); keybd_event(Btn.Tag, scancode, KEYEVENTF_EXTENDEDKEY OR 0, 0); keybd_event(Btn.Tag, scancode, KEYEVENTF_EXTENDEDKEY OR KEYEVENTF_KEYUP, 0); ImageList1.GetBitmap(2, ImgBtnClose.Picture.Bitmap); ImgBtnClose.Invalidate(); SetWindowPos(Self.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE); end; procedure TFormKeyBoard.FormMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin bMouseDown:=true; iDownX:=X; iDownY:=Y; SetWindowPos(self.Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE); end;
procedure TFormKeyBoard.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if(bMouseInForm=false) then begin bMouseInForm:=true; self.Color:=clActiveCaption; if(bStickLeft) then self.Left:=Screen.Width-self.Width // Show else self.Left:=0; // Show end; if(bMouseInXButton=true) then begin bMouseInXButton:=false; ImageList1.GetBitmap(2,ImgBtnClose.Picture.Bitmap); ImgBtnClose.Invalidate(); end; if(bMouseDown)then begin if(bStickLeft) then begin if(-X>Screen.Width*3/4) then begin bStickLeft:=false; self.Left:=0; end; end else begin if(X > Screen.Width*3/4) then begin bStickLeft:=true; self.Left:=Screen.Width - self.Width; end; end; // this->Left+=X-iDownX; // 因為我只想移動 Y 方向 self.Top:=self.Top + Y - iDownY; end; end; procedure TFormKeyBoard.FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin bMouseDown:=false; end; procedure TFormKeyBoard.ImgBtnCloseClick(Sender: TObject); begin Close; end; procedure TFormKeyBoard.ImgBtnCloseMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin if(bMouseInForm=false) then begin bMouseInForm:=true; self.Color:=clActiveCaption; if(bStickLeft) then self.Left:=Screen.Width-self.Width // Show else self.Left:=0; // Show end; if(bMouseInXButton=false) then begin bMouseInXButton:=true; ImageList1.GetBitmap(1,ImgBtnClose.Picture.Bitmap); ImgBtnClose.Invalidate(); end; end; procedure TFormKeyBoard.Timer1Timer(Sender: TObject); var hwndThisActived:THandle; LastActivedTitle:array[0..255]of char; MousePos:TPOINT; begin // Try to find the foreground windows hwndThisActived:=GetForegroundWindow(); if(hwndLastActived<>hwndThisActived) then begin if(hwndThisActived=self.Handle) then begin hwndThisActived:=hwndLastActived; if(hwndLastActived<>0) then SetForegroundWindow(hwndLastActived); end; SetWindowPos(self.Handle,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE or SWP_NOSIZE); hwndLastActived:=hwndThisActived;
GetWindowText(hwndLastActived,LastActivedTitle,256); self.Image1.Hint:=AnsiString(LastActivedTitle); end; if( (bMouseDown=false) and (bMouseInForm=true) ) then begin if ( GetCursorPos(MousePos) ) then begin if( (self.Left > MousePos.x)or (self.Top > MousePos.y) or ((self.Left+self.Width) < MousePos.x) or ((self.Top+self.Height) < MousePos.y) ) then begin bMouseInForm:=false; self.Color:=clNavy;//clInactiveCaption; if(bStickLeft) then self.Left:=Screen.Width-3 // Hide else self.Left:=3-self.Width; // Hide if(bMouseInXButton=true) then begin bMouseInXButton:=false; ImageList1.GetBitmap(2,ImgBtnClose.Picture.Bitmap); ImgBtnClose.Invalidate(); end; end; end; end; end; end.
|
|
|
|