请问如何使用自定的mouse 的X,Y数值控制mouse目前的位置?

如题,简单的说,希望在photon中可以利用自定的X,Y数值来移动mouse位置,并按下click,以用来选取某个位置上的button,谢谢!! :smiley:

得到当前位置和移动位置如下:

int button_activate( PtWidget_t *widget, ApInfo_t *apinfo, PtCallbackInfo_t *cbinfo )
{
	PhQueryCursor( 0, &buf );
	printf( "x=%d y=%d\n", buf.pos.x, buf.pos.y );

	int input_group = PhInputGroup( 0 );
	PhMoveCursorAbs( input_group, 60, 60 );
    
	/* eliminate 'unreferenced' warnings */
	widget = widget, apinfo = apinfo, cbinfo = cbinfo;

	return( Pt_CONTINUE );
}

模拟click应该是用PhEventEmit吧,没做过.

谢谢nakeyfish的回覆!!
我之前在help document中有找到PhEmit()及PhEventEmit() (我不是很了解这之前的差异),
并自己在某个button中的callback中写了个function试着去用他,
但当我呼叫完后就会死机,有点类似deadlock的状况, 整个program只剩右上角的X可以按!!
不知道可否帮我看一下那边写错了!!谢谢!!

In button callback:
int
Click_Button2( PtWidget_t *widget, ApInfo_t *apinfo, PtCallbackInfo_t *cbinfo )

{

/* eliminate ‘unreferenced’ warnings */
widget = widget, apinfo = apinfo, cbinfo = cbinfo;

MyPressMouse(20,20);

return( Pt_CONTINUE );

}


In MyPressMouse() function:
void MyPressMouse(int X, int Y)
{

PhRect_t rect;
PhPointerEvent_t EventData;

if( NULL == PhAttach( NULL, NULL ) ) {
fprintf( stderr,
“Couldn’t attach Photon channel.\n”);
exit( EXIT_FAILURE );
}
event.type = Ph_EV_BUT_PRESS;
event.subtype = 0;
event.flags = 0;
event.num_rects = 1;
event.data_len = sizeof(EventData);
event.emitter.rid = Ph_DEV_RID;

rect.ul.x = rect.lr.x = X;
rect.ul.y = rect.lr.y = Y;

EventData.buttons = Ph_BUTTON_SELECT ;
EventData.flags = 0;

PhEventEmit( &event, &rect, &EventData );

}

懒得try,给你个例子吧.如果要按键有动作像手动点一样.我想还需要自己加点代码.(60,60 的根据你button的位置改一下)

例子很简单,写一个新的photon的project, 放两个button.加两个callback.

/* Y o u r   D e s c r i p t i o n                       */
/*                            AppBuilder Photon Code Lib */
/*                                         Version 2.03  */

/* Standard headers */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

/* Local headers */
#include "ablibs.h"
#include "abimport.h"
#include "proto.h"

int debug = 1;
PhCursorInfo_t buf;
PhPoint_t btnwidgetpos;

struct
{
   PhEvent_t        event;
   PhRect_t         rect;
   PhPointerEvent_t pevent;
} MyFakePtrEvent;


int setup_f( PtWidget_t *link_instance, ApInfo_t *apinfo, PtCallbackInfo_t *cbinfo )
{
	PtArg_t arg[1];
	PtSetArg( &arg[0], Pt_ARG_POS, &btnwidgetpos, 0 );
	PtGetResources( ABW_PtButton_autoclick, 1, arg );
   
	/* eliminate 'unreferenced' warnings */
	link_instance = link_instance, apinfo = apinfo, cbinfo = cbinfo;

	return( Pt_CONTINUE );
}

int button_activate( PtWidget_t *widget, ApInfo_t *apinfo, PtCallbackInfo_t *cbinfo )
{
	PhQueryCursor( 0, &buf );
	printf( "x=%d y=%d\n", buf.pos.x, buf.pos.y );

	int input_group = PhInputGroup( 0 );
	PhMoveCursorAbs( input_group, 60, 60 );

	memset( &MyFakePtrEvent, 0, sizeof( MyFakePtrEvent ) );
   
	// fill in the event structure to reflect the emission of a fake pointer event
	MyFakePtrEvent.event.emitter.rid = 
	MyFakePtrEvent.event.collector.rid = PtWidgetRid( ABW_base );
	MyFakePtrEvent.event.processing_flags = Ph_FAKE_EVENT;
	MyFakePtrEvent.event.input_group = PhInputGroup( NULL );
	MyFakePtrEvent.event.flags = Ph_EVENT_INCLUSIVE;
	MyFakePtrEvent.event.data_len = sizeof( MyFakePtrEvent.pevent );
	MyFakePtrEvent.event.num_rects = 1;
    
	/*
    * the event is a point-source event, so we will use the 
    * Pt_ARG_POS associated with the widget we want to target 
    * to define a 1x1 pixel rectangle
    */
	MyFakePtrEvent.rect.ul.x = 
	MyFakePtrEvent.rect.lr.x = btnwidgetpos.x;
	MyFakePtrEvent.rect.ul.y = 
	MyFakePtrEvent.rect.lr.y = btnwidgetpos.y;
   
	//give us the data associated with the a single click of the left mouse button
	MyFakePtrEvent.pevent.pos.x = btnwidgetpos.x;
	MyFakePtrEvent.pevent.pos.y = btnwidgetpos.y;
	MyFakePtrEvent.pevent.click_count = 1;
	MyFakePtrEvent.pevent.buttons = 
	MyFakePtrEvent.pevent.button_state =
		Ph_BUTTON_SELECT;  /* left mouse btn. */

	/* emit mouse button press */
	if( debug )
		printf( "sending a fake left mouse btn press event\n" );
	MyFakePtrEvent.event.type = Ph_EV_BUT_PRESS;
	PtSendEventToWidget( ABW_PtButton_autoclick, (PhEvent_t *) &MyFakePtrEvent );


	/* 
    * emit button release events:
    *     Ph_EV_RELEASE_REAL goes to the widget where the 
    *        release genuinely took place
    *     Ph_EV_RELEASE_PHANTOM goes to the widget where the
    *        press event went (to let it be able to handle 
    *        things like Disarm callbacks)
    *     Ph_EV_RELEASE_ENDCLICK lets the widget know that 
    *        any sequence of multiple clicks that might have 
    *        been in progress have now stopped.
    */
	MyFakePtrEvent.event.type = Ph_EV_BUT_RELEASE;
	if( debug )
		printf( "sending fake mouse btn release (real) event\n" );
	MyFakePtrEvent.event.subtype = Ph_EV_RELEASE_REAL;
	PtSendEventToWidget( ABW_PtButton_autoclick, (PhEvent_t *) &MyFakePtrEvent );
    
	if( debug )
		printf( "sending fake mouse btn release (phantom) event\n" );
	MyFakePtrEvent.event.subtype = Ph_EV_RELEASE_PHANTOM;
	PtSendEventToWidget( ABW_PtButton_autoclick, (PhEvent_t *) &MyFakePtrEvent );

	if( debug )
		printf( "sending fake mouse btn release (endclick) event\n" );
	MyFakePtrEvent.event.subtype = Ph_EV_RELEASE_ENDCLICK;
	PtSendEventToWidget( ABW_PtButton_autoclick, (PhEvent_t *) &MyFakePtrEvent );
    
	/* eliminate 'unreferenced' warnings */
	widget = widget, apinfo = apinfo, cbinfo = cbinfo;

	return( Pt_CONTINUE );
}

int bt_autoclick_arm( PtWidget_t *widget, ApInfo_t *apinfo, PtCallbackInfo_t *cbinfo )
{
	printf( "OK\n" );

	/* eliminate 'unreferenced' warnings */
	widget = widget, apinfo = apinfo, cbinfo = cbinfo;

	return( Pt_CONTINUE );
}

哇…谢谢nakeyfish给的这个例子, 真的让我又学了不少, 有很多没看过的东西,对我这个新手而言帮助真的太大了, 我得好好研究一下!! :smiley:

否先请问一下, 例子中是用PtSendEventToWidget来控制event的, 这必需要知道是那个widget才行, 而不能以mouse的(X,Y)来自动判断, 这是否就是PtSendEventToWidget 与PhEmit之间的差异了呢?? :wink: