|
发表于 2010-6-30 13:48:43| 字数 3,476| - 中国–广东–广州–番禺区 广州海之光通讯技术有限公司
|
显示全部楼层
用Delphi写了个程序,利用这个传感器,当把笔记本竖起来的时候,屏幕自动旋转垂直,就像Thinkpad TabletPC,完整源代码如下。注意:程序运行时不显示窗体。附件是exe和源代码。该程序在T61p上测试通过。
视频:http://v.youku.com/v_show/id_XMTg1ODIwNjI4.html
program AutoRotate;
uses
Windows, Messages;
const
szAppName : PChar = 'AutoRotate';
ENUM_CURRENT_SETTINGS = $FFFFFFFF;
DMDO_DEFAULT = 0;
DMDO_90 = 1;
DMDO_180 = 2;
DMDO_270 = 3;
type
ACCELREPORT = record
PresentState: DWORD ; // Current internal state (stable: 0, unstable1: 1: unstable2: 2)
LatestRawAccelDataX: WORD ; // latest raw acceleration data of X axis <-- works!
LatestRawAccelDataY: WORD ; // latest raw acceleration data of Y axis <-- works!
LatestAccelDataX: WORD ; // latest acceleration data of X axis (average in 40ms) <-- Works even better?
LatestAccelDataY: WORD ; // latest acceleration data of Y axis (average in 40ms) <-- Works even better?
Temperature: CHAR ; // latest temperature
LatestZeroG_X: WORD ; // latest zero-G offset of X axis <-- Seems to be the current notion of "center"
LatestZeroG_Y: WORD ; // latest zero-G offset of Y axis <-- ""
end;
PACCELREPORT = ^ACCELREPORT;
var
sensorFunction: procedure (pAcceleration: PACCELREPORT); stdcall;
centerX, centerY: WORD;
wc : WNDCLASS;
HMainWnd : HWND;
AMsg : MSG;
nTimerId: THandle; //时钟标识
//窗体回调函数
function WndProc(AWnd:HWND; message:UINT; wp:WPARAM; lp:LPARAM):LRESULT;stdcall;
begin
Result := 0;
case message of
WM_DESTROY:
begin
KillTimer(0, nTimerId);
PostQuitMessage(0);
end
else
Result := DefWindowProc(AWnd, message, wp, lp);
end;
end;
procedure RotateScreen(nDegree: Integer);
var
dm: DEVMODE;
nOld: Integer;
dwTemp: DWORD;
begin
ZeroMemory(@dm, SizeOf(DEVMODE));
dm.dmSize := SizeOf(DEVMODE);
if EnumDisplaySettings(nil, ENUM_CURRENT_SETTINGS, dm) then
begin
nOld := dm.dmScale;
if nOld <> nDegree then
begin
if (((nOld = DMDO_DEFAULT) or (nOld = DMDO_180)) and ((nDegree = DMDO_90) or (nDegree = DMDO_270))) or
(((nOld = DMDO_90) or (nOld = DMDO_270)) and ((nDegree = DMDO_DEFAULT) or (nDegree = DMDO_180)))
then
begin
dwTemp := dm.dmPelsHeight;
dm.dmPelsHeight := dm.dmPelsWidth;
dm.dmPelsWidth := dwTemp;
end;
dm.dmScale := nDegree;
ChangeDisplaySettings(dm, 0);
end;
end;
end;
//加速传感器数据采集
function GetAccelDirect: ACCELREPORT;
var
hSensor: HMODULE;
begin
ZeroMemory(@Result, SizeOf(ACCELREPORT));
if @sensorFunction = nil then
begin
hSensor := LoadLibrary('Sensor.dll');
if hSensor <> 0 then
begin
sensorFunction := GetProcAddress(hSensor, 'ShockproofGetAccelerometerData');
if(@sensorFunction <> nil) then
begin
sensorFunction(@Result);
centerX := Result.LatestZeroG_X;
centerY := Result.LatestZeroG_Y;
end;
end;
end;
if @sensorFunction <> nil then
sensorFunction(@Result);
end;
//时钟回调函数
procedure MyTimerProc(hWnd: HWND; uMsg: UINT; idEvent: UINT; Time: DWORD); stdcall;
var
data: ACCELREPORT;
begin
ZeroMemory(@Data, SizeOf(ACCELREPORT));
data := GetAccelDirect;
if data.LatestAccelDataY - centerY < -60 then
RotateScreen(DMDO_270)
else
if Abs(data.LatestAccelDataY - centerY) < 20 then
RotateScreen(DMDO_DEFAULT)
else
if data.LatestAccelDataY - centerY > 60 then
RotateScreen(DMDO_90);
end;
//主程序
begin
with wc do
begin
style := CS_VREDRAW or CS_HREDRAW;
lpfnWndProc := @WndProc;
cbClsExtra := 0;
cbWndExtra := 0;
hIcon := LoadIcon(0, IDI_APPLICATION);
hCursor := LoadCursor(0, IDC_ARROW);
hbrBackground := GetSysColorBrush(COLOR_WINDOW);
hInstance := HInstance;
lpszMenuName := nil;
lpszClassName := szAppName;
end;
RegisterClass(wc);
HMainWnd := CreateWindow(szAppName,
szAppName,
WS_OVERLAPPEDWINDOW,
Integer(CW_USEDEFAULT), Integer(CW_USEDEFAULT),
Integer(CW_USEDEFAULT), Integer(CW_USEDEFAULT),
HWND_DESKTOP, 0,
HInstance, nil);
ShowWindow(HMainWnd, SW_HIDE);//CmdShow);
UpdateWindow(HMainWnd);
nTimerId := SetTimer(0, 1, 100, @MyTimerProc); {每 100ms 调用一次 MyTimerProc}
while GetMessage(AMsg, 0, 0, 0) do
begin
TranslateMessage(AMsg);
DispatchMessage(AMsg);
end;
end.
[ Edited by madfish on 2010-7-1 11:34 ] |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
x
|