Capturing the Talk Key? - Windows Mobile Development and Hacking General

I am pasting this from my post on the MS .NETCF Dev Forums:
========================8< snip ======================
Hello.
I cannot seem to find a complete example for this, and as I am new to using unmanaged code, I need a COMPLETE one. If there is a MANAGED way to do this - great, but I certainly can't find one. Even the SHCMBM_OVERRIDEKEY constant was buried so far into the docs I needed spelunking equipment to find it.
I am writing a Dialer App, mostly as proof of concept. I cannot figure out how to capture the Talk key in order to actually place the call.
I pulled some constants from winuser.h and aygshell.h:
Code:
public const int WM_USER = 0x0400;
public const int SHCMBM_OVERRIDEKEY = (WM_USER + 403);
public const int VK_F3 = 0x72;
public const int VK_TTALK = VK_F3;
public const int SHMBOF_NODEFAULT = 0x00000001; // do not do default handling of this key
public const int SHMBOF_NOTIFY = 0x00000002; // send us the WM_* messages for this key
and imported some funcs from coredll and aygshell:
Code:
[DllImport("coredll.dll", SetLastError=true)]
public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
[DllImport("aygshell", SetLastError=true)]
public static extern IntPtr SHFindMenuBar(IntPtr hwnd);
And then I have this call in InitializeComponent():
Code:
SendMessage((IntPtr)SHFindMenuBar(this.Handle), SHCMBM_OVERRIDEKEY, VK_TTALK, SHMBOF_NODEFAULT | SHMBOF_NOTIFY);
Now I have a couple of questions.
A - is there anything wrong with all of that?
and B - in other examples, I see people somehow getting ahold of a .Message property of the Form, but I don't seem to have System.Windows.Forms.Message anywhere... Not in the namespace or off the window object itself. I assume it's being passed back in some sort of event related to the form, but what?
I hope these aren't total n00b questions, but as I asid I am really unfamiliar with how unmanaged code really works, and have never done any Win32 C++ only vanilla C++ under unix.
Thanks in advance.
====================>8 unsnip =================
In case that's not clear: I want to make the green talk button NOT launch the phone's default dialer, but instead initiate the call from within MY dialer. The actual hardware button, not a softkey and not an on-screen button.
I am using an HTC Mogul.
.NETCF 2.0
VS2005
C#
and a partridge in a pear tree!
Any help would be MUCH appreciated. I am a little surprised that there doesn't seem to be an obvious way of doing it. Seems like a rather glaring omission to the managed SDK. Perhaps there is a way and I have just missed it.
Thanks!

Bump for the daytime crew.

Related

Simulate Button Click

Hi,
I am trying to simulate a PictureBox.Click event. I have searched these forums and the ones on MSDN with many different combinations of search terms.
However I cannot find anything!
Basically what I am trying to achieve is to fire the picturebox's click event from within my code. What I have read so far seems to indicate that I need to make a call to SendMessage (COM interop?) to actually make windows perform the click.
This is for the compact framework version 1.0.
Any help you can give would be great because this is all very new to me, I'm a web application developer by trade so i'm a fish out of water on this one!
OK, the other method that I am investigating is the use of the mouse_event as demonstrated in this article by Daniel Moth.
However I am struggling to find the namespace Win32Api anywhere in the framework so I'm struggling with that also.
*Update*
I have been able to simulate a click using mouse_event in a call to the coredll using the following code:
Code:
[DllImport("coredll")]
static extern bool SetCursorPos(int X, int Y);
[DllImport("coredll")]
static extern void mouse_event(uint dwFlags, uint dx, uint dy, uint dwData, int dwExtraInfo);
[Flags]
public enum MouseEventFlags
{
LEFTDOWN = 0x00000002,
LEFTUP = 0x00000004,
MIDDLEDOWN = 0x00000020,
MIDDLEUP = 0x00000040,
MOVE = 0x00000001,
ABSOLUTE = 0x00008000,
RIGHTDOWN = 0x00000008,
RIGHTUP = 0x00000010
}
bool tempVal = SetCursorPos(x, y);
mouse_event((uint)MouseEventFlags.LEFTDOWN, 0, 0, 0, 0);
mouse_event((uint)MouseEventFlags.LEFTUP, 0, 0, 0, 0);
however I have one outstanding problem (that I know of!).
I am struggling to capture the corrext X and Y co-ordinates of the control. I have tried many different methods and they all return values of 0 for both axis.
How do you guys do it?
Many Thanks
I haven't answered till now since I don't know .NET
But since you found your way to using native APIs I think I can help you.
This is how I would do it in C/C++:
Code:
RECT wndRect; //this is a structure that contains window top, left, bottom and right coordinates.
GetWindowRect(FindWind(L"[I]window class[/I]", L"[I]window name[/I]"), &wndRect);
x = wndRect.left + 1; //add 1 to window position to make sure the click is inside
y = wndRect.top + 1;
GetWindowRect returns the window position in screen coordinates for top left and bottom right corners.
For FindWindow to work you need to know the class and name of the window you want to find. You can find them using a utility called SPY++ which comes with any Microsoft C++ compiler.
The class is window type (so it will probably be something like 'PictureBox' or 'Image') and window name is most likely blank.
Hope this helps.
Thanks fo your help
I don't know if your code would have done the trick or not but I managed to work my way through the different class definitions to find what i needed.
Code:
int x = selectedButton.PointToScreen(selectedButton.Bounds.Location).X + 2;
int y = selectedButton.PointToScreen(selectedButton.Bounds.Location).Y + 2;
This still doesn't work but I really don't have time to work out why, all I know is that the call to SetCursorPos() returns false. I know the mouse_event code works because if I position the cursor over the Start button it opens the menu.
Time is of an essence so for now I'm just going to have to drop this and pray that I have time to finish this when towards the end of my project.
/me thinks writing my first Mobile 5.0 application in 4 days (I'm a web application developer by trade) was bad planning on the management's fault anyway
Thanks for your input though
use this method signature:
[DllImport("coredll")]
public static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
int instead of uint or long.
For me it worked.

Hiding/showing a form (vb.net)

I am trying to replace my contacts program with one I wrote myself but I'm having a little problem getting the form to hide and then show again?
I would like to start my app from a button, easy enough but I'm a little confused with hiding it again. I can hide the form but if I press the button again nothing happens but I'd like my app to show itself again?
Could someone please help the village idiot and point me in the right direction please?
Ok solved my problem. I used another exe to boot the program and if it was already booted then show the program via the API.
Imports System.Runtime.InteropServices
Imports System.Diagnostics
Module ModMain
<DllImport("coredll")> _
Public Function FindWindow(ByVal lpClass As String, ByVal lpTitle As String) As IntPtr
End Function
<DllImport("CoreDll")> _
Public Function ShowWindow(ByVal hwnd As IntPtr, ByVal nCmdShow As Integer) As Boolean
End Function
<DllImport("CoreDll")> _
Public Function SetForegroundWindow(ByVal hWnd As IntPtr) As Boolean
End Function
Const SW_HIDE As Integer = 0
Const SW_SHOW As Integer = 5
Public Sub Main()
Dim hWnd As Long = FindWindow("#NETCF_AGL_BASE_", "Contacts")
If hWnd = IntPtr.Zero Then
Dim AP As New Process
AP.StartInfo.FileName = "Program Files\ContactsList2\ContactsList2.exe"
AP.Start()
Else
ShowWindow(hWnd, SW_SHOW)
SetForegroundWindow(hWnd)
End If
End Sub
End Module

[Q] Converting an editable text box to be used as a integer

I have a edit able text box that is next to a button lets say onclick of the button it will take the text from the editable text box and converted to an integer so it can be subracted by.. oh lets say 32 so my first method was this.
number = EText.getText();
textOutcome.setText(number - 32);
this gave me an error of
The operator - is undefined for the argument type(s) Editable, int
my second attempt was
textOutcome.setText((Integer.parseInt(EText.getText().toString()) - 32));
This gave me no errors and it ran fine untill i clicked the button which causes the command above to run. and it force closed my application.
Does any one have any ideas i can do, or any sample code?
Thanks,
Blue.
Bumping the topic.
Please can anyone help me with this..!
Have you tried stepping through the code with the debugger? Otherwise, the code you posted looks fine. There is probably something else at play here.
Basicall it force closes whea subtraction is made..
Sent from my Samsung Epic 4g.
Ahh the debugger found something early in the code thanks for the idea !
You have to do any mathematical arithmetic with the integer type, not with string, So when you extract the number from the EditText you have to convert the string into a integer, or whatever type of number it may be.
WHen you have the integer then you can apply the arithmetic.
when this is done you then have to convert the total into a string type again.
Hope this helps.
So basically im going to write a little of code off the top of my head which obviously can have errors. Since im not testing it.
EditText txbox = (EditText)findViewById(R.id.EditText01);
String txdata = txbox.getText().toString();
int txval = Integer.ParseInt(txdata);
//you should make sure that the value is an integer, if not i think //Integer.ParseInt() will just cut off the rest if its irrational.
//Now you can do arithmetic//
int b = 2;
int t;
t = txval - b;
//The total value is in variable t.
So lets convert this into a string and put it back into an object like edittext or textview
txbox.setText(String.valueOf(t));
//Thats all, hope that helps.

[Q] Easy string initialize question

Hi,
I am reading a book on Android development. In one of the source code examples the author uses the construct:
String tt = **;
I assume he is initializing his new string to empty, but I have never seen this before and just want to be sure. There is probably a more detailed meaning.
Google search doesn't find anything like this. Can someone confirm what this means?
Thanks for any info or pointers to the definition.
Barry.
Uh, that's an error.
// Initialize String, 2 ways
String tt = null; // I always use this
String tt = ""; // empty string can be unpredictable

Set Device Time from Server

Hi,
Does anybody know how to pull the time from a server and use that time to update the devices clock?
I want to lock the Clock down on the device so the best way to ensure the time is correct is to sync it with a server.
I'm using VB.net.
Give this a spin.
It sets the get the UTC time, from http://www.timeapi.org/ , but have a look at the site to see what else it can do.
Your device should deal with your timezone offset from UTC automatically.
I used .NET Reflector to translate into VB from C#, hence the odd definition of some variables.
Code:
Public Structure SYSTEMTIME
Public wYear As UInt16
Public wMonth As UInt16
Public wDayOfWeek As UInt16
Public wDay As UInt16
Public wHour As UInt16
Public wMinute As UInt16
Public wSecond As UInt16
Public wMilliseconds As UInt16
End Structure
Declare Function GetSystemTime Lib "CoreDll.dll" _
(ByRef lpSystemTime As SYSTEMTIME) As UInt32
Declare Function SetSystemTime Lib "CoreDll.dll" _
(ByRef lpSystemTime As SYSTEMTIME) As UInt32
Private Shared Sub Main(ByVal args As String())
Dim Buffer As Byte() = New Byte(&H19 - 1) {}
Dim DateItems As String() = New String(8 - 1) {}
Dim Separators As Char() = New Char() { "-"c, "-"c, "T"c, ":"c, ":"c, "+"c, ":"c }
Dim Now As New SYSTEMTIME
Program.GetSystemTime((Now))
Dim ResponseStream As Stream = WebRequest.Create("http://www.timeapi.org/utc/now").GetResponse.GetResponseStream
ResponseStream.Read(Buffer, 0, &H19)
ResponseStream.Close
DateItems = Encoding.UTF8.GetString(Buffer, 0, &H19).Split(Separators)
Now.wYear = Convert.ToUInt16(DateItems(0))
Now.wMonth = Convert.ToUInt16(DateItems(1))
Now.wDay = Convert.ToUInt16(DateItems(2))
Now.wHour = Convert.ToUInt16(DateItems(3))
Now.wMinute = Convert.ToUInt16(DateItems(4))
Now.wSecond = Convert.ToUInt16(DateItems(5))
Now.wMilliseconds = 0
Program.SetSystemTime((Now))
End Sub
The original C# code is here. You will have to convert the C# 'using' statements to VB 'Imports'
Code:
using System;
using System.Net;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
namespace GetTime
{
class Program
{
[DllImport("coredll.dll")]
private extern static void GetSystemTime(ref SYSTEMTIME lpSystemTime);
[DllImport("coredll.dll")]
private extern static uint SetSystemTime(ref SYSTEMTIME lpSystemTime);
private struct SYSTEMTIME
{
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
}
static void Main(string[] args)
{
byte[] Buffer = new byte[25];
string DateString;
string[] DateItems = new string[8];
char[] Separators = new char[7] { '-', '-', 'T', ':', ':', '+', ':' };
SYSTEMTIME Now = new SYSTEMTIME();
GetSystemTime(ref Now);
Stream ResponseStream = WebRequest.Create("http://www.timeapi.org/utc/now").GetResponse().GetResponseStream();
ResponseStream.Read(Buffer, 0, 25);
ResponseStream.Close();
DateString = Encoding.UTF8.GetString(Buffer, 0, 25);
DateItems = DateString.Split(Separators);
Now.wYear = Convert.ToUInt16(DateItems[0]);
Now.wMonth = Convert.ToUInt16(DateItems[1]);
Now.wDay = Convert.ToUInt16(DateItems[2]);
Now.wHour = Convert.ToUInt16(DateItems[3]);
Now.wMinute = Convert.ToUInt16(DateItems[4]);
Now.wSecond = Convert.ToUInt16(DateItems[5]);
Now.wMilliseconds = 0;
SetSystemTime(ref Now);
}
}
}
Here's how it works: The call to the URL returns the date/time as a char buffer.
"2011-12-02T14:56:38+00:00" as an example.
After converting this to a string we convert it into an array of strings in DateItems[] as
2011
12
02
14
56
38
00
00
using Separators[] to split the fields apart.
These are then converted to ushort values in the time structure, before setting the time on the device with it.
Nice code stephj .
Cheers!!!
Thanks for that stephj, will give it a go.
i've tried this and i'm getting a :
The remote server returned an error: (407) Proxy Authentication Required.
any ideas?
I tried the above program on an emulated device connected to the net via its host PC's connection and it worked a treat.
To get through a proxy, you will need to add the following code.
Code:
Program.GetSystemTime((Now))
**************INSERT THIS ****************
Dim Proxy as new WebProxy("http://ProxyServer:80/",true)
proxy.Credentials = CredentialCache.DefaultCredentials
WebRequest.DefaultWebProxy = proxy
**************INSERT ENDS ****************
Dim ResponseStream As Stream = WebRequest.Create("http://www.timeapi.org/utc/now").GetResponse.GetResponseStream
Where the first parameter of the WebProxy constructor is the name of your proxy server, and the port it uses. Here at work, we can get away with just using our proxy server's internal network DNS name of "Internet:8080", to access the outside web through a Microsoft ISA Proxy/Firewall. Note in this case the proxy uses a different port number of 8080 as opposed to the default http port of 80. If yours is not 80 you will have to provide it. You may have to do some groundwork to track down the name of your proxy server, and the port it uses. I would start by looking at the proxy setup in Settings->Connections->'Set up my proxy server' for starters.
CredentialCache.DefaultCredentials, picks up your default login/credentials and passes them to the proxy server. If it works properly, you should go through it, seamlessly.
Good luck!
Hi steph,
i tweaked this slightly and set up a webreference in my program, i then pull the time down from that in the format of "2011-12-12T09:43:14", it then splits it.
The problem i am having is that sometimes it seems to add an hour to the time.
Any ideas?
What time zone is your device operating under?
Start->Settings->[System]->Clock & Alarms->[Time]
What's the zone, and is it Home or Visiting? - I'll see if I can duplicate it.
GMT London and is set as Home.
As a test I set the time on the device to: 01/06/1999 and time 01:00:00. When i run the program the first time i press my 'Update Time' button and it returns 12/12/11 and 12:53:04, so 1 hour ahead. If i press the button again I get the correct time.
I notice on your original post that the time returned had +00:00 on the end but you dont seem to use it when you break the string down, is this not required?
Thanks for the help, much appreciated
At least I can duplicate it, so that is a start. It only seems to throw the hour forward if the date has changed, which explains why the second call to it corrects the time.
If you just knock the time back a couple of hours, a single call of the program sets the correct time.
Interesting. I'll try and get to the bottom of it, might take a day or so, on and off.
Edit: Got it!
The 1st of June 1999 is in BST one hour in front of GMT/UTC. The first call changes the date and time using BST, leaving the time pushed forward one hour. The date is then set to today's date which is in GMT/UTC. The second call sets the time against the GMT Timezone which corrects the time.
Set the date time to 04:00 yesterday and it works fine.
I'll see if we can fix it a bit better. More later.........
Here's the cure: It's C#, I'll leave you to convert it to VB.
The secret is to set the time twice, but stall the thread for ten seconds inbetween. The device will sort itself out in the gap, as various time and date housekeeping tasks are triggered. The second SetTime(), will carry out the final fix of the time before the program finally ends.
This should also work in BST when changing from a GMT/UTC date, and should also work with all global time zones.
Add this:
Code:
using System.Threading;
SetSystemTime(ref Now);
Thread.Sleep(10000);
SetSystemTime(ref Now);
that's great steph, thanks again.
There is a minor problem with the previous code:- If the minute happens to roll over in the 10 seconds while the process is asleep, then the change of minute will be lost.
Here's a better solution. Create a DateTime object in which to store the returned date and time from the WebRequest().
Use it to set the system date/time, and then advance it forward ten seconds.
Set the date/time with it again, after the ten second sleep() has elapsed.
Seems to work O.K. Post bug reports to this thread, if you find it doesn't.
Code:
using System;
using System.Net;
using System.Text;
using System.Threading;
using System.IO;
using System.Runtime.InteropServices;
namespace GetTime
{
class Program
{
[DllImport("coredll.dll")]
private extern static uint SetSystemTime(ref SYSTEMTIME lpSystemTime);
private struct SYSTEMTIME
{
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
}
static void Main(string[] args)
{
byte[] Buffer = new byte[25];
string DateString;
string[] DateItems = new string[8];
char[] Separators = new char[7] { '-', '-', 'T', ':', ':', '+', ':' };
SYSTEMTIME Now = new SYSTEMTIME();
Stream ResponseStream = WebRequest.Create("http://www.timeapi.org/utc/now").GetResponse().GetResponseStream();
ResponseStream.Read(Buffer, 0, 25);
ResponseStream.Close();
DateString = Encoding.UTF8.GetString(Buffer, 0, 25);
DateItems = DateString.Split(Separators);
DateTime SaveTime = new DateTime(Convert.ToInt32(DateItems[0]),Convert.ToInt32(DateItems[1]),Convert.ToInt32(DateItems[2]),Convert.ToInt32(DateItems[3]),Convert.ToInt32(DateItems[4]),Convert.ToInt32(DateItems[5]));
Now.wYear = Convert.ToUInt16(SaveTime.Year);
Now.wMonth = Convert.ToUInt16(SaveTime.Month);
Now.wDay = Convert.ToUInt16(SaveTime.Day);
Now.wHour = Convert.ToUInt16(SaveTime.Hour);
Now.wMinute = Convert.ToUInt16(SaveTime.Minute);
Now.wSecond = Convert.ToUInt16(SaveTime.Second);
Now.wMilliseconds = 0;
SetSystemTime(ref Now);
SaveTime.AddSeconds(10);
Thread.Sleep(10000);
Now.wYear = Convert.ToUInt16(SaveTime.Year);
Now.wMonth = Convert.ToUInt16(SaveTime.Month);
Now.wDay = Convert.ToUInt16(SaveTime.Day);
Now.wHour = Convert.ToUInt16(SaveTime.Hour);
Now.wMinute = Convert.ToUInt16(SaveTime.Minute);
Now.wSecond = Convert.ToUInt16(SaveTime.Second);
SetSystemTime(ref Now);
}
}
}
C# .NET CF 2.0 WinMo 5.0 onwards executable is included in the zip file.
It is a console application, so don't expect anything much to happen until the 'hourglass' disappears.
If the first SetSystemTime() ends up changing the date across a Daylight Saving Boundary date, then, during the sleep() period, the device's housekeeping date/time/alarm services will probably retrigger any outstanding task and event reminders for 'today'.
P.S. GetSystemTime() can be dropped it is not required.
works like a charm steph, nice one. thanks.
@stephj, Thanks for the updated code .
Cheers!!!
Seem to be having a problem with this since UK has put the clocks forward an hour, every time I update using this code my device is adding an hour to the time.
The device is an M3 Mobile.
What are the settings on the Start-> Settings->Clock and Alarms->Time[Tab]
It should still have the Home radio button active and the time zone set to GMT London, Dublin. The mobile device should take care of daylight saving itself.
Is your M3 running WinMo 6.1 or 6.5? But I can't see it making much difference.
Works OK on a stock 6.1 Kaiser (Vodafone v1615)
Update: Also seems to work OK on the WM 6.5.3 Professional emulator.
wubbledoos said:
Hi,
Does anybody know how to pull the time from a server and use that time to update the devices clock?
I want to lock the Clock down on the device so the best way to ensure the time is correct is to sync it with a server.
I'm using VB.net.
Click to expand...
Click to collapse
Well on my Kaisers (running either wm 6.1 or 6.5) I use SKTsync to sync my device clock to one of the NIST or SNTP servers. It's freeware and it does it all for you, all you do is run the app. It's soooo simple. I also run an app called CT Scheduler lite. I use it to automatically run SKTsync every night.

Categories

Resources