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

如何讓滑鼠游標固定不動呢?

尚未結案
dodohua1010
一般會員


發表:2
回覆:0
積分:0
註冊:2007-03-04

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-03-17 12:42:57 IP:218.175.xxx.xxx 訂閱
Dear all:

請問各位一個 mouse 游標定位 問題 :

我要寫一個十字線標線程式 在目標點(pixel)時可以 將十字線定住 十字線我寫出來囉 不過把十字線定住後 游標也跟著跑 我希望游標也不要跑 看暸幾本書好像都沒寫道 這樣功能不知道各位大大有遇過這樣問題嗎?
<textarea name="code" class="cpp" rows="10" cols="60"> void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,TShiftState Shift, int X, int Y) { if (Button==mbLeft && x2==0) { for(i=0;i<=500;i ) { Form1->Canvas->MoveTo(X,Y); Form1->Canvas->LineTo(X,Y); i = i 1; } } ............... </textarea>
GGump
一般會員


發表:2
回覆:16
積分:8
註冊:2006-08-04

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-01-03 10:25:53 IP:122.124.xxx.xxx 訂閱
目前我是使用計時器迅速地將滑鼠游標移回定位,還不知道有沒有更好的辦法
syntax
尊榮會員


發表:26
回覆:1139
積分:1258
註冊:2002-04-23

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-01-06 01:05:13 IP:61.64.xxx.xxx 訂閱
這跟書無關,跟你的腦筋有關

你要換個方式思考

要滑鼠游標不動,那在 OnMouseMove 處理

但是你的問題敘述很籠統,貼個圖來看看你要的效果,最清楚

===================引 用 dodohua1010 文 章===================
Dear all:

請問各位一個 mouse 游標定位 問題 :

我要寫一個十字線標線程式 在目標點(pixel)時可以 將十字線定住 十字線我寫出來囉 不過把十字線定住後 游標也跟著跑 我希望游標也不要跑 看暸幾本書好像都沒寫道 這樣功能不知道各位大大有遇過這樣問題嗎?
<textarea cols="60" rows="10" class="cpp" name="code"> void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,TShiftState Shift, int X, int Y) { if (Button==mbLeft && x2==0) { for(i=0;i<=500;i ) { Form1->Canvas->MoveTo(X,Y); Form1->Canvas->LineTo(X,Y); i = i 1; } } ............... </textarea>
dodohua
一般會員


發表:0
回覆:1
積分:0
註冊:2005-09-03

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-01-22 18:42:26 IP:60.248.xxx.xxx 訂閱
1.謝謝syntax說的 forbidden 回家再翻一下 這東西看看

2.以下是我之前提的內容

|
|
---------- ------------
|
|

說明: 無法插圖~只好要簡單畫一下 如上圖
問題(1): 我現在用timer來控制 一個十字線(游標 加上用垂直/水平 line) 現在我可以游標指到哪 十字線就跟到哪
但是怎麼讓游標固定呢? 我想用滑鼠右鍵控制游標不要動



問題(2):如何讓十字線跟著游標走 不會Delay??
說明:我知道是用timer來控制十字線才會 有delay現象 不過我若把timer時間設很短 可以比較快移動 不過卻有
閃爍問題
怎麼控制不閃爍呢?傷腦筋

RootKit
資深會員


發表:16
回覆:358
積分:419
註冊:2008-01-02

發送簡訊給我
#5 引用回覆 回覆 發表時間:2008-01-22 20:09:06 IP:61.222.xxx.xxx 訂閱
不去理解您要做的東西,讓滑鼠固定,就是用MOUSE HOOK 方式。

但嘗試理解你要做的事情,無法理解為何要讓滑鼠固定。
應該是當點擊位置後,記憶該位置。讓滑鼠繼續可以移動,但十字線不動。

使用Timer ,當然會有閃爍的情形,因為不斷的要畫面刷新。
因該先分析什麼事件需要刷新畫面,並且清楚約定 InvalidateRect 範圍。

至於會不會Delay 跟寫法以及畫法有關。
可使用 DoubleBuffered 方式解決。

你對於物件及視窗的GDI還不是很熟悉。建議找本書看一看。
或者找個寧靜的夜晚好好想一想。
nisson
一般會員


發表:2
回覆:12
積分:22
註冊:2008-01-31

發送簡訊給我
#6 引用回覆 回覆 發表時間:2008-02-14 00:05:08 IP:218.174.xxx.xxx 訂閱
問題一.如何定住游標?
最好的方式就是,定位以後先隱藏游標(因為已經有十字標),然後把定位值儲存起來,
當須要游標的時候,再讓游標從定位點秀出來.
ShowCursor(False);===隱藏游標
POINT pt;
GetCursorPos(&pt);===取得游標定位值
----------------------------------------------------------
ShowCursor(true);===秀出游標
SetCursorPos(&pt);===讓游標回到定位點
問題二.TIMER?
送你一個高精準度的timer(保證不delay).
將sptimer.h sptimer.cpp兩個檔案copy到 lib底下然後將sptimer.cpp安裝成元件.
sptimer.h
//---------------------------------------------------------------------------
#ifndef AnimTimerH
#define AnimTimerH
//---------------------------------------------------------------------------
#include
#include
#include
#include <Forms.hpp><br />//---------------------------------------------------------------------------
class PACKAGE TAnimTimer : public TComponent
{
public:
__fastcall TAnimTimer(TComponent* Owner);
virtual __fastcall ~TAnimTimer();
__published:
__property bool Enabled = {read=FEnabled,write=SetEnabled,default=true};
__property unsigned int Interval = {read=FInterval,write=SetInterval,default=10};
__property TNotifyEvent OnTimer = {read=FOnTimer,write=SetOnTimer};
protected:
bool FEnabled;
unsigned int FInterval;
TNotifyEvent FOnTimer;
virtual void __fastcall SetInterval(unsigned int newinterval);
virtual void __fastcall SetEnabled(bool newenabled);
virtual void __fastcall SetOnTimer(TNotifyEvent newevent);
HWND hwnd;
virtual void __fastcall Start();
virtual void __fastcall Stop(); // blocking
virtual void __fastcall Alert(); // blocking
virtual void __fastcall InternalWndProc(TMessage &Message);
virtual void __fastcall UpdateTimer();
virtual void __fastcall Timer();
static void ThreadFunction(void *lParam);
};


//---------------------------------------------------------------------------
#endif


sptimer.cpp
#include
#include
#pragma hdrstop
#include
#include "AnimTimer.h"
USERES("AnimTimer.dcr");
USEPACKAGE("vcl40.bpi");
//---------------------------------------------------------------------------
#pragma package(smart_init)
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*){ return 1;}
//---------------------------------------------------------------------------
namespace Animtimer
{
class TThreadMiser;
enum TThreadMessageCode {tmcHadEnough=1, tmcThreadTimer=2, tmcAlertThread=3};
typedef struct {
HWND hwnd; // set at thread creation
CRITICAL_SECTION critsec;
bool IsHwndValid;
HANDLE hChangeEvent;
unsigned long idThread;
unsigned long hThread;
TThreadMiser *miser;
} TThreadData;
}

//---------------------------------------------------------------------------
namespace Animtimer
{
class TThreadMiser : public TComponent
{
public:
HANDLE FHandle; TAnimTimer *FTimer;
__fastcall TThreadMiser(TComponent *AOwner);
__fastcall ~TThreadMiser();
__property HANDLE Handle = {read=FHandle,write=FHandle};
__property TAnimTimer* AnimTimer={read=FTimer,write=FTimer};
void __fastcall Notification(TComponent *c,TOperation op);
};
}

__fastcall Animtimer::TThreadMiser::TThreadMiser(TComponent *AOwner):TComponent(AOwner)
{ FHandle=NULL; FTimer=NULL; }
void __fastcall Animtimer::TThreadMiser::Notification(TComponent *c,TOperation op)
{ TComponent::Notification(c,op);
if (c==AnimTimer && op==opRemove) AnimTimer=NULL;
}
__fastcall Animtimer::TThreadMiser::~TThreadMiser()
{ if (AnimTimer!=NULL)
{
delete AnimTimer; AnimTimer=NULL;
}
if (FHandle!=NULL)
{ DWORD res=WaitForSingleObject(FHandle,5000);
if (res==WAIT_TIMEOUT)
{
}
CloseHandle(FHandle);
FHandle=NULL;
}
}
void TAnimTimer::ThreadFunction(void *lParam)
{ Animtimer::TThreadData *td=(Animtimer::TThreadData*)lParam;

HWND hwnd=td->hwnd;
bool mustquit=false;
bool isvalid;
bool hadenough=false;

MSG msg;
TIMECAPS timecaps; timeGetDevCaps(&timecaps,sizeof(timecaps));
timeBeginPeriod(timecaps.wPeriodMin);
while (!mustquit)
{
bool res;
if (hadenough)
{
res=true; GetMessage(&msg,NULL,0,0xFFFF);
}
else
{ res=PeekMessage(&msg,NULL,0,0xFFFF,PM_REMOVE); }
if (res)
{ if (msg.message==WM_QUIT)
{
mustquit=true;

}
else
{
}
}
if (!mustquit && !hadenough)
{ DWORD starttime,period,endtime;
EnterCriticalSection(&td->critsec);
isvalid=td->IsHwndValid;
LeaveCriticalSection(&td->critsec);
if (isvalid)
{ starttime=timeGetTime();
period=SendMessage(hwnd,WM_APP,Animtimer::tmcThreadTimer,0);
endtime=timeGetTime();
}
if (isvalid)
{ switch (period)
{ case -1: break; // not even a sleep
case -2: // had enough.
{ hadenough=true;
PostMessage(hwnd,WM_APP,Animtimer::tmcHadEnough,0);
} break;
default:
{ DWORD sleeptime=0;
if (starttime period>endtime) sleeptime=starttime period-endtime;
if (sleeptime==0) Sleep(0);
else
{ DWORD res=WaitForSingleObject(td->hChangeEvent,sleeptime);
if (res==WAIT_OBJECT_0) ResetEvent(td->hChangeEvent);
}
}
}
}
}
}
CloseHandle(td->hChangeEvent);
td->miser->Handle=NULL;
timeEndPeriod(timecaps.wPeriodMin);
Application->RemoveComponent(td->miser);
delete td;
}

__fastcall TAnimTimer::TAnimTimer(TComponent* Owner): TComponent(Owner)
{ IsMultiThread=true;
hwnd=NULL;
if (!ComponentState.Contains(csDesigning)) hwnd=AllocateHWnd(this->InternalWndProc);
FEnabled=true;
FInterval=10;
UpdateTimer();
}
__fastcall TAnimTimer::~TAnimTimer()
{ FEnabled=false;
UpdateTimer();
if (hwnd!=NULL) DeallocateHWnd(hwnd); hwnd=NULL;
}
void __fastcall TAnimTimer::Timer()
{ if (FOnTimer!=NULL) FOnTimer(this);
}
void __fastcall TAnimTimer::SetEnabled(bool newenabled)
{ if (newenabled==FEnabled) return;
FEnabled=newenabled;
UpdateTimer();
}
void __fastcall TAnimTimer::SetInterval(unsigned int newinterval)
{ if (FInterval==newinterval) return;
FInterval=newinterval;
Alert();
}
void __fastcall TAnimTimer::SetOnTimer(TNotifyEvent val)
{ FOnTimer=val;
UpdateTimer();
}
void __fastcall TAnimTimer::UpdateTimer()
{ if (hwnd==NULL) return;
Stop();
if (FEnabled && FOnTimer!=NULL) Start();
}
void __fastcall TAnimTimer::InternalWndProc(TMessage &Message)
{ Message.Result=DefWindowProc(hwnd,Message.Msg,Message.WParam,Message.LParam);
switch (Message.Msg)
{ case WM_APP:
{ switch (Message.WParam)
{ case Animtimer::tmcHadEnough:
{
Animtimer::TThreadData *td=(Animtimer::TThreadData*)GetWindowLong(hwnd,GWL_USERDATA);
if (td==NULL)
{
}
else
{ EnterCriticalSection(&td->critsec);
td->IsHwndValid=false;
LeaveCriticalSection(&td->critsec);
PostThreadMessage(td->idThread,WM_QUIT,0,0);
}
SetWindowLong(hwnd,GWL_USERDATA,0);
} break;
case Animtimer::tmcThreadTimer:
{ Animtimer::TThreadData *td=(Animtimer::TThreadData *)GetWindowLong(hwnd,GWL_USERDATA);
if (td!=NULL && Enabled) Timer();
Message.Result=FInterval;
} break;
case Animtimer::tmcAlertThread:
{ Animtimer::TThreadData *td=(Animtimer::TThreadData *)GetWindowLong(hwnd,GWL_USERDATA);
if (td!=NULL) SetEvent(td->hChangeEvent);
} break;
}
} break;
}
}
void __fastcall TAnimTimer::Start()
{ Animtimer::TThreadData *td;
if (hwnd==NULL)
{
return;
}
td=(Animtimer::TThreadData*)GetWindowLong(hwnd,GWL_USERDATA);
if (td!=NULL)
{
return;
}
td=new Animtimer::TThreadData;
SetWindowLong(hwnd,GWL_USERDATA,(LONG)td);
InitializeCriticalSection(&td->critsec);
td->hChangeEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
td->hwnd=hwnd;
td->IsHwndValid=TRUE;
HANDLE holdThread;
holdThread=(HANDLE)_beginthreadNT(ThreadFunction,4096,td,NULL,0,&(td->idThread));
HANDLE hThread;
DuplicateHandle(GetCurrentProcess(),holdThread,GetCurrentProcess(),&hThread,0,TRUE,DUPLICATE_SAME_ACCESS);
td->hThread=(unsigned long)hThread;
Animtimer::TThreadMiser *miser=new Animtimer::TThreadMiser(Application);
miser->Handle=(HANDLE)td->hThread;
miser->AnimTimer=this; FreeNotification(miser);
td->miser=miser;
HANDLE hThisT=GetCurrentThread();
HANDLE hThatT=(HANDLE)td->hThread;
int pr=GetThreadPriority(hThisT);
SetThreadPriority(hThatT,pr-1);
}
void __fastcall TAnimTimer::Stop()
{ if (hwnd==NULL)
{
return;
}
Animtimer::TThreadData *td=(Animtimer::TThreadData*)GetWindowLong(hwnd,GWL_USERDATA);
if (td==NULL)
{
return;
}
EnterCriticalSection(&td->critsec);
td->IsHwndValid=false;
LeaveCriticalSection(&td->critsec);
PostThreadMessage(td->idThread,WM_QUIT,0,0);
SetWindowLong(hwnd,GWL_USERDATA,0);
}
void __fastcall TAnimTimer::Alert()
{ if (hwnd==NULL)
{
return;
}
SendMessage(hwnd,WM_APP,Animtimer::tmcAlertThread,0);
}

//---------------------------------------------------------------------------
namespace Animtimer
{ void __fastcall PACKAGE Register()
{ TComponentClass classes[1] = {__classid(TAnimTimer)};
RegisterComponents("SpTimer", classes, 0);
}
}
//---------------------------------------------------------------------------
nisson
一般會員


發表:2
回覆:12
積分:22
註冊:2008-01-31

發送簡訊給我
#7 引用回覆 回覆 發表時間:2008-02-14 00:10:11 IP:218.174.xxx.xxx 訂閱
抱歉筆誤請將sptimer.h sptimer.cpp改成AnimTimer.h AnimTimer.cpp
joycat
一般會員


發表:4
回覆:6
積分:2
註冊:2004-02-23

發送簡訊給我
#8 引用回覆 回覆 發表時間:2008-07-05 07:36:09 IP:59.125.xxx.xxx 訂閱
您的 Timer 的 include 部分 有漏掉程式碼唷
系統時間:2024-05-08 0:10:59
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!