線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:12628
推到 Plurk!
推到 Facebook!

螢幕數字鍵盤(含 Source)

 
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-09-18 10:33:38 IP:211.76.xxx.xxx 未訂閱
主要參考及回應: ■【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://www.ViewMove.com
附加檔案:56498_testKeyboard.zip
bigdogchina
版主


發表:238
回覆:523
積分:312
註冊:2003-04-28

發送簡訊給我
#2 引用回覆 回覆 發表時間:2004-09-18 11:24:49 IP:211.162.xxx.xxx 未訂閱
厲害,厲害,萬分敬仰!!! ================================= 人生在勤,不索何獲 業精於勤荒於嬉,行成於思毀於隨 臨淵羡魚不如退而結網
------
人生在勤,不索何获?
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#3 引用回覆 回覆 發表時間:2004-09-21 08:19:02 IP:211.76.xxx.xxx 未訂閱
conundrum 大大所貼的: ■【轉貼】螢幕軟鍵盤  http://delphi.ktop.com.tw/topic.php?TOPIC_ID=56391 不是使用 WS_EX_NOACTIVATE 用的是 AttachThreadInput() 這個 API,改天再來改寫一個吧  < href="http://www.softking.com.tw/soft/click_share.asp?fid3=1833" target="blank">StatPlus 系統資源監測器(on SoftKing) 視動科技 VMASK - ViewMove Automation Software Kernel
------
http://www.ViewMove.com
conundrum
尊榮會員


發表:893
回覆:1272
積分:643
註冊:2004-01-06

發送簡訊給我
#4 引用回覆 回覆 發表時間:2004-09-21 18:56:48 IP:61.221.xxx.xxx 未訂閱
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 利害 期待 小鍵盤 再現江湖 哈哈  發表人 -
dllee
站務副站長


發表:321
回覆:2519
積分:1711
註冊:2002-04-15

發送簡訊給我
#5 引用回覆 回覆 發表時間:2004-09-22 09:33:27 IP:220.139.xxx.xxx 未訂閱
M$ 的 OSK 沒有使用 WS_EX_NOACTIVATE (由其 Windows 的狀態可知) 也沒有使用 AttachThreadInput() (由其 Import Function List 可知) 而是使用其他的方式。    StatPlus 系統資源監測器 @ SoftKing 視動科技 VMASK - ViewMove Automation Software Kernel
------
http://www.ViewMove.com
teddywolf
一般會員


發表:0
回覆:1
積分:0
註冊:2004-09-24

發送簡訊給我
#6 引用回覆 回覆 發表時間:2004-09-24 14:52:29 IP:210.21.xxx.xxx 未訂閱
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

發送簡訊給我
#7 引用回覆 回覆 發表時間:2009-03-19 16:28:46 IP:203.75.xxx.xxx 訂閱
我把他改成 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.
系統時間:2024-03-29 6:12:53
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!