SHGetFileInfo() - Windows Mobile Development and Hacking General

How to Use the SHGetFileInfo Function to Get the Icons That Are Associated with Files in Visual C#/vb .NET Compact Framework ( in PocketPC, SmartPhone, and WinCE Devices )
Thanx.
M. GANESAN

PeaceWorld said:
How to Use the SHGetFileInfo Function to Get the Icons That Are Associated with Files in Visual C#/vb .NET Compact Framework ( in PocketPC, SmartPhone, and WinCE Devices )
Thanx.
M. GANESAN
Click to expand...
Click to collapse
I would suggest you to either changing the language (program in c++) or use wrapped unmanaged code to achieve that.
I'm sure you will find some code on http://www.codeproject.com that encapsulate the SHGetFileInfo call.
Cheers,
.Fred

This works for me
Just call: GetIcon(".txt") and you'll get the Picture index inside
packageView->ImageList->Images
Code:
#pragma region GetIcon
public:
[StructLayout(LayoutKind::Sequential)]
value struct SHFILEINFO
{
IntPtr hIcon;
int iIcon;
UInt32 dwAttributes;
[MarshalAs(UnmanagedType::ByValTStr,SizeConst=260)]
String^ szDisplayName;
[MarshalAs(UnmanagedType::ByValTStr,SizeConst=80)]
String^ szTypeName;
};
static UInt32 SHGFI_ICON = 0x100;
static UInt32 SHGFI_SMALLICON = 0x1;
static UInt32 SHGFI_USEFILEATTRIBUTES = 0x000000010;
static UInt32 FILE_ATTRIBUTE_NORMAL = 0x00000080;
[DllImport("shell32.dll")] static IntPtr SHGetFileInfo(String^ pszPath, UInt32 dwFileAttributes, IntPtr psfi, UInt32 cbSizeFileInfo, UInt32 uFlags);
[DllImport("User32.dll")] static int DestroyIcon(IntPtr hIcon);
int GetIcon(String^ file)
{
if(packageView->ImageList->Images->ContainsKey(file)) return packageView->ImageList->Images->IndexOfKey(file);
IntPtr pShinfo = Marshal::AllocHGlobal(Marshal::SizeOf(SHFILEINFO::typeid));
SHGetFileInfo(file, FILE_ATTRIBUTE_NORMAL, pShinfo, Marshal::SizeOf(SHFILEINFO::typeid), SHGFI_USEFILEATTRIBUTES | SHGFI_ICON | SHGFI_SMALLICON);
SHFILEINFO^ i = (SHFILEINFO^)Marshal::PtrToStructure(pShinfo, SHFILEINFO::typeid);
Marshal::FreeHGlobal(pShinfo);
packageView->ImageList->Images->Add(file, System::Drawing::Icon::FromHandle(i->hIcon)->ToBitmap());
DestroyIcon(i->hIcon);
return packageView->ImageList->Images->IndexOfKey(file);
}
#pragma endregion
BTW:
packageView is a TreeView...
and yes, you should use c++

Related

Programmatically cycle sound icon (sound/vibrate/mute)

When you click on the sound icon, you get the two sliders and three radio buttons. Anyone know how to set those radio buttons through code (C++) so it gets reflected in the icon display (and actually changes the "profile")?. I'd like to change to vibrate/mute/sound at different times using something like alarmToday to run a small app.
Thanks,
sbl
I wrote a profiles app in .net and C++ here are some code snippets;
You can change the registry values for the volumes (I cant remember which as I wrote it a long time ago), then you need to call the following to have the values applied.
// ProfilesHelper.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "ProfilesHelper.h"
#include <windows.h>
#include <Soundfile.h>
void WINEXPORT SetSoundMode(int mode)
{
// Initialize an empty SNDFILEINFO structure
SNDFILEINFO sndfile = {0};
if (mode == 0)
sndfile.sstType = SND_SOUNDTYPE_ON;
if (mode == 1)
sndfile.sstType = SND_SOUNDTYPE_VIBRATE;
if (mode == 2)
sndfile.sstType = SND_SOUNDTYPE_NONE;
SndSetSound(SND_EVENT_ALL, &sndfile, false);
void AudioUpdateFromRegistry();
}
void WINEXPORT SetSystemVolume(long volume)
{
waveOutSetVolume(NULL, volume);
void AudioUpdateFromRegistry();
}
Hi,
I have a similar need of programatically cycling the sound icon to MUTE VIBRATE and normal volume icon. I can do it successfully on Windows Mobile 5.0. I created a sample application with Visual Studio 2005 for WM 5.0 and I am able to set the icons as i want. But when i tried it for PPC2003 I was not able to compile that. Missing SoudFile.h. Can any one help me to find out how to do the same thing on PPC2003 specifically i-mate devices like PDA2 and PDA2K.
Thanks
With Regards,
Bhagat Nirav K.
i know its a 2 ur old post..but i need help also now
how can i mute sounds using C# in .net 2.0 for WM6
Just forget about this header file...
Operate on HKCU\ControlPanel\Notifications\ShellOverrides\Mode value. It can have 3 states: 0 == normal, 1 == vibrate and 2 == silent. That's all
Probably you need to call AudioUpdateFromRegistry function from coredll.dll.
Or... another method
look at HKCU\ControlPanel\Sounds\RingTone0:Sound, it takes 3 different values:
*none*
*vibrate*
your ringtone name, taken from SavedSound value in the same key.
Hi,
Firstly I know this post is way old, but I thought of responding to it since I was stuck on this topic for a couple of days and couldnt find a way to resolve it.
Also others having this problem will also be redirected here through various search results as I was. So to aid them
1. Meddling with the registry to change the sound profiles didnt work for me. I tried Changing the Mode inHKCU\ControlPanel\Notifications\ShellOverrides\Mode but that didnt work on my phone.
2. What I currently have working is the following code - C# with Pinvoke
public enum SND_SOUNDTYPE
{
On,
File,
Vibrate,
None
}
private enum SND_EVENT
{
All,
RingLine1,
RingLine2,
KnownCallerLine1,
RoamingLine1,
RingVoip
}
[StructLayout(LayoutKind.Sequential)]
private struct SNDFILEINFO
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szPathName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
public SND_SOUNDTYPE sstType;
}
[DllImport("coredll.dll")]
public static extern void AudioUpdateFromRegistry ();
[DllImport("aygshell.dll", SetLastError = true)]
private static extern uint SndSetSound(SND_EVENT seSoundEvent, ref SNDFILEINFO pSoundFileInfo, bool fSuppressUI);
static void SetProfileNormal()
{
SNDFILEINFO soundFileInfo = new SNDFILEINFO();
soundFileInfo.sstType = SND_SOUNDTYPE.On;
uint num = SndSetSound(SND_EVENT.All, ref soundFileInfo, true);
AudioUpdateFromRegistry();
}
static void SetProfileVibrate()
{
SNDFILEINFO soundFileInfo = new SNDFILEINFO();
soundFileInfo.sstType = SND_SOUNDTYPE.Vibrate;
uint num = SndSetSound(SND_EVENT.All, ref soundFileInfo, true);
AudioUpdateFromRegistry();
}
static void SetProfileMuted()
{
SNDFILEINFO soundFileInfo = new SNDFILEINFO();
soundFileInfo.sstType = SND_SOUNDTYPE.None;
uint num = SndSetSound(SND_EVENT.All, ref soundFileInfo, true);
AudioUpdateFromRegistry();
}
Hope this helps

Using ShellExecuteEx using Visual Studio 2003 (C#/VB.NET)

Hi there,
OK, I took the hint about using shellexececuteex, but I can't find a code snippet which does the trick!
I found this link which gives some good code, but when I put it in my VB.NET app, it doesn't seem to like it.
At the line
Code:
DllImport("coredll") _
Private Shared Function ShellExecuteEx(ByVal ex As SHELLEXECUTEEX) As Integer
it says "Statement is not valid in namespace."
and
Code:
<DllImport("coredll")> _
Private Shared Function LocalAlloc(flags As Integer, size As Integer) As IntPtr()
says "Statement cannot appear within a method body. End of method assumed.
Can anyone point me in the right direction? Once I know what I'm doing (which may be a while!), I've got some funky stuff I want to do, but I need to figure out what I'm doing wrong first...
Thanks
Jon "The Nice Guy
Code:
Imports System.Runtime.InteropServices
Imports System.Text
Class SHELLEXECUTEEX
Public cbSize As Integer
Public fMask As Integer
Public hwnd As IntPtr
Public lpVerb As IntPtr
Public lpFile As IntPtr
Public lpParameters As IntPtr
Public lpDirectory As IntPtr
Public nShow As Integer
Public hInstApp As IntPtr
' Optional members
Public lpIDList As IntPtr
Public lpClass As IntPtr
Public hkeyClass As IntPtr
Public dwHotKey As UInt32
Public hIcon As IntPtr
Public hProcess As IntPtr
End Class 'SHELLEXECUTEEX
<DllImport("coredll")> _
Private Shared Function ShellExecuteEx(ByVal ex As SHELLEXECUTEEX) As Integer
<DllImport("coredll")> _
Private Shared Function LocalAlloc(flags As Integer, size As Integer) As IntPtr()
<DllImport("coredll")> Private Shared Sub LocalFree(ptr As IntPtr)
' Code starts here
Dim docname As String = "\windows\default.htm"
Dim nSize As Integer = docname.Length * 2 + 2
Dim pData As IntPtr = LocalAlloc(&H40, nSize)
Marshal.Copy(Encoding.Unicode.GetBytes(docname), 0, pData, nSize - 2)
Dim see As New SHELLEXECUTEEX
see.cbSize = 60
see.dwHotKey = 0
see.fMask = 0
see.hIcon = IntPtr.Zero
see.hInstApp = IntPtr.Zero
see.hProcess = IntPtr.Zero
see.lpClass = IntPtr.Zero
see.lpDirectory = IntPtr.Zero
see.lpIDList = IntPtr.Zero
see.lpParameters = IntPtr.Zero
see.lpVerb = IntPtr.Zero
see.nShow = 0
see.lpFile = pData
ShellExecuteEx(see)
LocalFree(pData)
If you want to start an executable, take a look at the following example which uses createprocess in VB using API
http://samples.gotdotnet.com/quickstart/CompactFramework/doc/waitforsingleobject.aspx
And some other interesting information using ShellExecute and Process.Start
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=404967&SiteID=1
Eelco
I need to execute a m3u file, or (in another case) a cab file.
I can't help you with the .NET stuff, but if you are trying to install cabs programatically you should read up on wceload.exe and it's parameters.
Unfortunately this will still require the use of CreateProcess (something that is very easy in native code, but apparently not so in .NET) but you will have control over several things like messages asking were to install and progress bar being shown.
http://msdn.microsoft.com/library/d...n-us/wcepbguide5/html/wce50lrfWceloadTool.asp
Bump
Just to let you all know, I got around needing the .cab file thang by installing the MrClean AUK2 ROM. I still want to be able to launch files with any extension though.
Jon
Use the registry to find out what program should launch for that extension and then launch that program with the file name as a parameter.
Which is what I was after in this thread where people told me to use ShellExecuteEX! LOL
If you can tell me how to get the application handler from the registry based on a file extension, then I'll write it into my app, otherwise, I'll need to use the ShellExecuteEX to launch the file, and let Windows handle the extension.

Finding Windows and their executable filepaths

I've just spent a lot of time looking for ways to tie Windows and process exe files together and I saw a lot of people asking after similar topics.
It was somewhat frustrating because of numerous little difficulties - using CreateToolhelp32Snapshot unpredictably fails, GetProcessById is no good if the process wasn't started with StartInfo, because you can have multiple windows to a process it's hard to identify which is a processes mainwindow.
But I solved my problem, a solution that I haven't seen elsewhere, so I thought I'd share it here. This is my solution to the specific problem of finding a window to match an executable file path....
This is on WM6, using CF2 in C#.
Used as follows (with S2U2 as the example):
Ionwerks.Window w = new Ionwerks.Window(@"\Program Files\S2U2\S2U2.exe");
IntPtr WindowsHandle = w.handle;
Code:
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace Ionwerks
{
delegate int EnumWindowsProc(IntPtr hwnd, IntPtr lParam);
class Window
{
private EnumWindowsProc callbackDelegate;
private IntPtr callbackDelegatePointer;
private IntPtr m_handle = IntPtr.Zero;
private string moduleFileName = "";
//Construct from path
public Window(string path)
{
moduleFileName = path;
Enumerate();
}
public IntPtr handle
{
get
{
return m_handle;
}
}
private void Enumerate() {
callbackDelegate = new EnumWindowsProc(EnumWindowsCallbackProc);
callbackDelegatePointer = Marshal.GetFunctionPointerForDelegate(callbackDelegate);
EnumWindows(callbackDelegatePointer, 0);
}
[DllImport("coredll.dll", SetLastError = true)]
private static extern bool EnumWindows(IntPtr lpEnumFunc, uint lParam);
[DllImport("coredll.dll", EntryPoint = "GetModuleFileNameW", SetLastError = true)]
private static extern uint GetModuleFileName(IntPtr hModule, [MarshalAs(UnmanagedType.LPWStr)] string lpFileName, uint nSize);
[DllImport("coredll")]
private static extern uint GetWindowThreadProcessId(IntPtr hwnd, out int lpdwProcessId);
[DllImport("coredll.dll")]
private static extern IntPtr OpenProcess(int flags, bool fInherit, int PID);
[DllImport("coredll.dll")]
private static extern bool CloseHandle(IntPtr handle);
[DllImport("coredll.dll")]
private static extern bool IsWindowVisible(IntPtr handle);
private string ModuleFileName = new string((char)0x20, 255);
private int EnumWindowsCallbackProc(IntPtr hwnd, IntPtr lParam)
{
//get windows process
int pid = 0;
GetWindowThreadProcessId(hwnd, out pid);
IntPtr pHnd = OpenProcess(0, false, pid);
//get processes image
GetModuleFileName(pHnd, ModuleFileName, (uint)ModuleFileName.Length);
//if paths match up
if (String.Compare(ModuleFileName.Substring(0, ModuleFileName.IndexOf('\0')), moduleFileName, true) == 0) {
//only interested in processes mainwindow
if (hwnd == Process.GetProcessById(pid).MainWindowHandle)
{
m_handle = hwnd;
}
}
CloseHandle(pHnd);
return 1;
}
}
}
thanks man! your code helped!
simple explanation ... ?.... what that codes for and how to use

GPS Intermediate Driver parsed API - in VB?

Is anyone currently using the GPS Intermediate Driver parsed API in VB?
I'm looking to get started but needing a bit of a kick-start. I've found the API to be used and it seems simple enough with only 4 functions but I don't see an example of anyone using it in VB, anywhere...
From the example in C++ from the SDK the DLL has the following functions but I don't know how to convert to VB, can anyone give a hand?
#region PInvokes to gpsapi.dll
[DllImport("gpsapi.dll")]
static extern IntPtr GPSOpenDevice(IntPtr hNewLocationData, IntPtr hDeviceStateChange, string szDeviceName, int dwFlags);
[DllImport("gpsapi.dll")]
static extern int GPSCloseDevice(IntPtr hGPSDevice);
[DllImport("gpsapi.dll")]
static extern int GPSGetPosition(IntPtr hGPSDevice, IntPtr pGPSPosition, int dwMaximumAge, int dwFlags);
[DllImport("gpsapi.dll")]
static extern int GPSGetDeviceState(IntPtr pGPSDevice);
#endregion
Thanks,
can you post the c++ code here. we can try and rebuild the data structures for vb which would allow you to execute the dll functions. (I would od it but I'm at work, not access)
How much of the code are you interested in?
In case anyone is interested I was able to find an unwilling soul to convert the first signature.
Here is the signature in C#:
[DllImport("gpsapi.dll")]static extern IntPtr GPSOpenDevice( IntPtr hNewLocationData, IntPtr hDeviceStateChange, string szDeviceName, int dwFlags);In VB, it looks like this:
In VB:
<DllImport("gpsapi.dll")> _Function Shared GPSOpenDevice( _ ByVal hNewLocationData As IntPtr, _ ByVal hDeviceStateChange As IntPtr, _ ByVal szDeviceName As String, _ ByVal dwFlags As Integer) As IntPtrEnd Function
hopefully some others can help come up with some simple VB source for using the GPS device....
I believe this is from a class module:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
using System;
using System.Runtime.InteropServices;
using System.Collections;
using System.Text;
namespace Microsoft.WindowsMobile.Samples.Location
{
public delegate void LocationChangedEventHandler(object sender, LocationChangedEventArgs args);
public delegate void DeviceStateChangedEventHandler(object sender, DeviceStateChangedEventArgs args);
/// <summary>
/// Summary description for GPS.
/// </summary>
public class Gps
{
// handle to the gps device
IntPtr gpsHandle = IntPtr.Zero;
// handle to the native event that is signalled when the GPS
// devices gets a new location
IntPtr newLocationHandle = IntPtr.Zero;
// handle to the native event that is signalled when the GPS
// device state changes
IntPtr deviceStateChangedHandle = IntPtr.Zero;
// handle to the native event that we use to stop our event
// thread
IntPtr stopHandle = IntPtr.Zero;
// holds our event thread instance
System.Threading.Thread gpsEventThread = null;
event LocationChangedEventHandler locationChanged;
/// <summary>
/// Event that is raised when the GPS locaction data changes
/// </summary>
public event LocationChangedEventHandler LocationChanged
{
add
{
locationChanged += value;
// create our event thread only if the user decides to listen
CreateGpsEventThread();
}
remove
{
locationChanged -= value;
}
}
event DeviceStateChangedEventHandler deviceStateChanged;
/// <summary>
/// Event that is raised when the GPS device state changes
/// </summary>
public event DeviceStateChangedEventHandler DeviceStateChanged
{
add
{
deviceStateChanged += value;
// create our event thread only if the user decides to listen
CreateGpsEventThread();
}
remove
{
deviceStateChanged -= value;
}
}
/// <summary>
/// True: The GPS device has been opened. False: It has not been opened
/// </summary>
public bool Opened
{
get { return gpsHandle != IntPtr.Zero; }
}
public Gps()
{
}
~Gps()
{
// make sure that the GPS was closed.
Close();
}
/// <summary>
/// Opens the GPS device and prepares to receive data from it.
/// </summary>
public void Open()
{
if (!Opened)
{
// create handles for GPS events
newLocationHandle = CreateEvent(IntPtr.Zero, 0, 0, null);
deviceStateChangedHandle = CreateEvent(IntPtr.Zero, 0, 0, null);
stopHandle = CreateEvent(IntPtr.Zero, 0, 0, null);
gpsHandle = GPSOpenDevice(newLocationHandle, deviceStateChangedHandle, null, 0);
// if events were hooked up before the device was opened, we'll need
// to create the gps event thread.
if (locationChanged != null || deviceStateChanged != null)
{
CreateGpsEventThread();
}
}
}
/// <summary>
/// Closes the gps device.
/// </summary>
public void Close()
{
if (gpsHandle != IntPtr.Zero)
{
GPSCloseDevice(gpsHandle);
gpsHandle = IntPtr.Zero;
}
// Set our native stop event so we can exit our event thread.
if (stopHandle != IntPtr.Zero)
{
EventModify(stopHandle, eventSet);
}
// block until our event thread is finished before
// we close our native event handles
lock (this)
{
if (newLocationHandle != IntPtr.Zero)
{
CloseHandle(newLocationHandle);
newLocationHandle = IntPtr.Zero;
}
if (deviceStateChangedHandle != IntPtr.Zero)
{
CloseHandle(deviceStateChangedHandle);
deviceStateChangedHandle = IntPtr.Zero;
}
if (stopHandle != IntPtr.Zero)
{
CloseHandle(stopHandle);
stopHandle = IntPtr.Zero;
}
}
}
/// <summary>
/// Get the position reported by the GPS receiver
/// </summary>
/// <returns>GpsPosition class with all the position details</returns>
public GpsPosition GetPosition()
{
return GetPosition(TimeSpan.Zero);
}
/// <summary>
/// Get the position reported by the GPS receiver that is no older than
/// the maxAge passed in
/// </summary>
/// <param name="maxAge">Max age of the gps position data that you want back.
/// If there is no data within the required age, null is returned.
/// if maxAge == TimeSpan.Zero, then the age of the data is ignored</param>
/// <returns>GpsPosition class with all the position details</returns>
public GpsPosition GetPosition(TimeSpan maxAge)
{
GpsPosition gpsPosition = null;
if (Opened)
{
// allocate the necessary memory on the native side. We have a class (GpsPosition) that
// has the same memory layout as its native counterpart
IntPtr ptr = Utils.LocalAlloc(Marshal.SizeOf(typeof(GpsPosition)));
// fill in the required fields
gpsPosition = new GpsPosition();
gpsPosition.dwVersion = 1;
gpsPosition.dwSize = Marshal.SizeOf(typeof(GpsPosition));
// Marshal our data to the native pointer we allocated.
Marshal.StructureToPtr(gpsPosition, ptr, false);
// call native method passing in our native buffer
int result = GPSGetPosition(gpsHandle, ptr, 500000, 0);
if (result == 0)
{
// native call succeeded, marshal native data to our managed data
gpsPosition = (GpsPosition)Marshal.PtrToStructure(ptr, typeof(GpsPosition));
if (maxAge != TimeSpan.Zero)
{
// check to see if the data is recent enough.
if (!gpsPosition.TimeValid || DateTime.Now - maxAge > gpsPosition.Time)
{
gpsPosition = null;
}
}
}
// free our native memory
Utils.LocalFree(ptr);
}
return gpsPosition;
}
Sorry had to post the remaining source in another thread:
/// <summary>
/// Queries the device state.
/// </summary>
/// <returns>Device state information</returns>
public GpsDeviceState GetDeviceState()
{
GpsDeviceState device = null;
// allocate a buffer on the native side. Since the
IntPtr pGpsDevice = Utils.LocalAlloc(GpsDeviceState.GpsDeviceStructureSize);
// GPS_DEVICE structure has arrays of characters, it's easier to just
// write directly into memory rather than create a managed structure with
// the same layout.
Marshal.WriteInt32(pGpsDevice, 1); // write out GPS version of 1
Marshal.WriteInt32(pGpsDevice, 4, GpsDeviceState.GpsDeviceStructureSize); // write out dwSize of structure
int result = GPSGetDeviceState(pGpsDevice);
if (result == 0)
{
// instantiate the GpsDeviceState class passing in the native pointer
device = new GpsDeviceState(pGpsDevice);
}
// free our native memory
Utils.LocalFree(pGpsDevice);
return device;
}
/// <summary>
/// Creates our event thread that will receive native events
/// </summary>
private void CreateGpsEventThread()
{
// we only want to create the thread if we don't have one created already
// and we have opened the gps device
if (gpsEventThread == null && gpsHandle != IntPtr.Zero)
{
// Create and start thread to listen for GPS events
gpsEventThread = new System.Threading.Thread(new System.Threading.ThreadStart(WaitForGpsEvents));
gpsEventThread.Start();
}
}
/// <summary>
/// Method used to listen for native events from the GPS.
/// </summary>
private void WaitForGpsEvents()
{
lock (this)
{
bool listening = true;
// allocate 3 handles worth of memory to pass to WaitForMultipleObjects
IntPtr handles = Utils.LocalAlloc(12);
// write the three handles we are listening for.
Marshal.WriteInt32(handles, 0, stopHandle.ToInt32());
Marshal.WriteInt32(handles, 4, deviceStateChangedHandle.ToInt32());
Marshal.WriteInt32(handles, 8, newLocationHandle.ToInt32());
while (listening)
{
int obj = WaitForMultipleObjects(3, handles, 0, -1);
if (obj != waitFailed)
{
switch (obj)
{
case 0:
// we've been signalled to stop
listening = false;
break;
case 1:
// device state has changed
if (deviceStateChanged != null)
{
deviceStateChanged(this, new DeviceStateChangedEventArgs(GetDeviceState()));
}
break;
case 2:
// location has changed
if (locationChanged != null)
{
locationChanged(this, new LocationChangedEventArgs(GetPosition()));
}
break;
}
}
}
// free the memory we allocated for the native handles
Utils.LocalFree(handles);
// clear our gpsEventThread so that we can recreate this thread again
// if the events are hooked up again.
gpsEventThread = null;
}
}
#region PInvokes to gpsapi.dll
[DllImport("gpsapi.dll")]
static extern IntPtr GPSOpenDevice(IntPtr hNewLocationData, IntPtr hDeviceStateChange, string szDeviceName, int dwFlags);
[DllImport("gpsapi.dll")]
static extern int GPSCloseDevice(IntPtr hGPSDevice);
[DllImport("gpsapi.dll")]
static extern int GPSGetPosition(IntPtr hGPSDevice, IntPtr pGPSPosition, int dwMaximumAge, int dwFlags);
[DllImport("gpsapi.dll")]
static extern int GPSGetDeviceState(IntPtr pGPSDevice);
#endregion
#region PInvokes to coredll.dll
[DllImport("coredll.dll")]
static extern IntPtr CreateEvent(IntPtr lpEventAttributes, int bManualReset, int bInitialState, StringBuilder lpName);
[DllImport("coredll.dll")]
static extern int CloseHandle(IntPtr hObject);
const int waitFailed = -1;
[DllImport("coredll.dll")]
static extern int WaitForMultipleObjects(int nCount, IntPtr lpHandles, int fWaitAll, int dwMilliseconds);
const int eventSet = 3;
[DllImport("coredll.dll")]
static extern int EventModify(IntPtr hHandle, int dwFunc);
#endregion
}
}
Well I've made a little progress but once again I'm stumped since I don't program in C..
Currently I'm able to open and close the GPS device on my phone but in order to retrieve information I believe I need a stuct converted to VB. I'm not familiar with struct so I'm hoping someone can explain it to me and or maybe help convert it.
These are the functions that have been converted to VB from C:
'Put this at the top of your module.
'Required in all cases when calling API functions
Imports System.Runtime.InteropServices
'Required in this example and any API function which
'use a string buffer. Provides the StringBuilder class
Imports System.Text
Public Class Form1
<DllImport("gpsapi.dll", EntryPoint:="GPSOpenDevice", SetLastError:=True, CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Winapi)> _
Public Shared Function GPSOpenDevice(ByVal hNewLocationData As IntPtr, ByVal hDeviceStateChange As IntPtr, ByVal szDeviceName As String, ByVal dwFlags As Integer) As IntPtr
End Function
<DllImport("gpsapi.dll", EntryPoint:="GPSCloseDevice", SetLastError:=True, CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Winapi)> _
Public Shared Function GPSCloseDevice(ByVal hGPSDevice As IntPtr) As Integer
End Function
<DllImport("gpsapi.dll", EntryPoint:="GPSGetPosition", SetLastError:=True, CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Winapi)> _
Public Shared Function GPSGetPosition(ByVal hGPSDevice As IntPtr, ByVal pGPSPosition As IntPtr, ByVal dwMaximumAge As Integer, ByVal dwFlags As Integer) As Integer
End Function
<DllImport("gpsapi.dll", EntryPoint:="GPSGetDeviceState", SetLastError:=True, CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Winapi)> _
Public Shared Function GPSGetDeviceState(ByVal pGPSDevice As IntPtr) As Integer
End Function
Click to expand...
Click to collapse
and this is the struct I need help with:
typedef struct _GPS_POSITION {
DWORD dwVersion;
DWORD dwSize;
DWORD dwValidFields;
DWORD dwFlags;
SYSTEMTIME stUTCTime;
double dblLatitude;
double dblLongitude;
float flSpeed;
float flHeading;
double dblMagneticVariation;
float flAltitudeWRTSeaLevel;
float flAltitudeWRTEllipsoid;
GPS_FIX_QUALITY FixQuality;
GPS_FIX_TYPE FixType;
GPS_FIX_SELECTION SelectionType;
float flPositionDilutionOfPrecision;
float flHorizontalDilutionOfPrecision;
float flVerticalDilutionOfPrecision;
DWORD dwSatelliteCount;
DWORD rgdwSatellitesUsedPRNs[GPS_MAX_SATELLITES];
DWORD dwSatellitesInView;
DWORD rgdwSatellitesInViewPRNs[GPS_MAX_SATELLITES];
DWORD rgdwSatellitesInViewElevation[GPS_MAX_SATELLITES];
DWORD rgdwSatellitesInViewAzimuth[GPS_MAX_SATELLITES];
DWORD rgdwSatellitesInViewSignalToNoiseRatio[GPS_MAX_SATELLITES];
} GPS_POSITION, *PGPS_POSITION;
Click to expand...
Click to collapse
I think the struct works like some type of callback which even that I'm not familiar with but as you try and retrieve information from the function 'GPSGetPosition' it uses the struct to do the work? just a guess...
Anyway I'm hoping someone can help me out as I feel I'm close but unless I can pull GPS data at still at ground zero...
TW,
Simple solution: Compile C# (this is NOT C+++) code to dll library. Then reference library from VB.NET solution.
C# and VB.NET are compiled both to IL.
Here is the needed code and declarations in C#.
<Your path>'Windows Mobile 6 SDK\Samples\PocketPC\CS\GPS\GpsPosition.cs"
Since I'm a bit green - are there some examples of doing this somewhere that I can take a look at?
"C# and VB.NET are compiled both to IL."
I don't follow what your saying here? what does IL stand for?
Thanks,
My friend,
why sample?
IL = Intermediate Language - VB.NET and C# are compiled to intermediatate language.
.Net Framework is languaage independent - You can compile C# code to dll and then reference (add reference) this dll in VB.NET project and use types form C# dll directly.
Thanks, I certainly appreciate your patience...
OK, I'll remember to use VB.NET as opposed to .NET in the future since there is a difference that I was unaware of, thanks for that.
Since I want to run this application on my phone I assume I need to create a new project in VB.Net - WM6 class library. Can I simply copy over the references and source form the original SDK and then build the .dll from there or am I over simplifying?
After building the .dll, in the application I want to create I make the reference to the new .dll, got it, when I want to reference the struct of the 'GPSGetPosition' function how would I do that?
TW,
[EDIT]
Doing more reading and learning a bit.
I think using a dll is the way to go and I believe there is a dll included in the sample. That brings me back to the Q of implementation. I've added a reference to the dll but since I'm only using the functions built within the dll how should I pass the GPS_POSITION struct listed above? does that still need to be converted to VB.Net then passed?
Semi manual marshhalling of structure to pointer:
Dim pointerM As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(myStruct))
Marshal.StructureToPtr(myStruct, pointerM, False)
Marshal.FreeHGlobal(pnt)
Click to expand...
Click to collapse
Since the above doesn't seem to pass anything to the struct is this used for sizing the struct to be passed?
OK.
Here is the compiled dll.
Add reference from vb.net project to dll.
Then (conceptual code in the pretty poor verbose VB.NET syntax )
Dim gps As new Gps()
AddHandler gps.DeviceStateChanged , DeviceStateChanged
AddHandler gps.LocationChanged, LocationChanged
gps.Open();
Public Sub LocationChanged(sender As object, args as LocationChangedEventArgs)
'Do something
args.Position.LatitudeInDegreesMinutesSeconds
args.position.LongitudeInDegreesMinutesSeconds
End Sub
Public Sub DeviceStateChanged(object sender, DeviceStateChangedEventArgs args)
'Do something
//GPS driver state
args.DeviceState;
End Sub
End of work with gps:
gps.Close()
//edit: Remove zip extension from gps.dll.zip - gps.dll is a valid name of assembly
RStein,
Thanks for your help. I managed to get it going with your assistance, it's much appreciated.
The .dll you compiled is not complete and errors though..
Dlli is a complete - from gps managed sample.
What's the error You're talking about?
As I said in other zda thread - intermediate driver doesn't work correctly on some Devices/ROM because of the error in the Microsoft/OEM implementaton (Htc Artemis).. http://groups.google.com/group/microsoft.public.pocketpc.developer/msg/2cedd69b906d4b7e
And finaly - GPS intermediate must be of course active in the control panel.
This is the error generated:
System.MissingMethodException was unhandled
Message: File or assembly name 'Microsoft.WindowsMobile.Samples.Location, Version=1.0.2985.26108, Culture=neutral, PublicKeyToken=null', or one of its dependencies, was not found.
System.TypeLoadException was unhandled
Message: An unhandled exception of type 'System.TypeLoadException' occurred in Unknown Module.
Click to expand...
Click to collapse
Thx,
Please rename gps.dll to Microsoft.WindowsMobile.Samples.Location.dll
And here is the project in VB - functional
I'm using VB.Net for Windows Mobile 5, but still not working
I want to use the GPS Intermediate Driver because I want to let the GPS to be used for other apps, such as the Google Maps for WM and other.
I did the following code, but I still not getting the right result... I did a program using the Serial connection, but Google Maps and other cannot use the GPS at the same time.
So... what am I doing wrong?
Here my code, any clues?
REM Declare Function GPSOpenDevice Lib "gpsapi.dll" (ByVal hNewLocationData As IntPtr, ByVal hDeviceStateChange As IntPtr, ByVal szDeviceName As String, ByVal dwFlags As Integer) As IntPtr
<DllImport("gpsapi.dll", EntryPoint:="GPSOpenDevice", SetLastError:=True, CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Winapi)> _
Public Shared Function GPSOpenDevice(ByVal hNewLocationData As IntPtr, ByVal hDeviceStateChange As IntPtr, ByVal szDeviceName As String, ByVal dwFlags As Integer) As IntPtr
End Function
REM Declare Function GPSCloseDevice Lib "gpsapi.dll" (ByVal hGPSDevice As IntPtr) As Integer
<DllImport("gpsapi.dll", EntryPoint:="GPSCloseDevice", SetLastError:=True, CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Winapi)> _
Public Shared Function GPSCloseDevice(ByVal hGPSDevice As IntPtr) As Integer
End Function
REM Declare Function GPSGetDeviceState Lib "gpsapi.dll" (ByVal pGPSDevice As IntPtr) As Integer
<DllImport("gpsapi.dll", EntryPoint:="GPSGetDeviceState", SetLastError:=True, CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Winapi)> _
Public Shared Function GPSGetDeviceState(ByVal pGPSDevice As IntPtr) As Integer
End Function
REM Declare Function GPSGetPosition Lib "gpsapi.dll" (ByVal hGPSDevice As IntPtr, ByVal pGPSPosition As IntPtr, ByVal dwMaximumAge As Integer, ByVal dwFlags As Integer) As Integer
<DllImport("gpsapi.dll", EntryPoint:="GPSGetPosition", SetLastError:=True, CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.Winapi)> _
Public Shared Function GPSGetPosition(ByVal hGPSDevice As IntPtr, ByVal pGPSPosition As GPS_POSITION, ByVal dwMaximumAge As Integer, ByVal dwFlags As Integer) As Integer
End Function
Const dwSize As Long = 0
Const dwVersion As Long = 1
Const dwFlags As Long = 0
Const dwValidFields As Long = 0
Const GPS_MAX_SATELLITES As Long = 12
<StructLayout(LayoutKind.Sequential)> Public Structure GPS_POSITION
Dim dwVersion As Long
Dim dwSize As Long
Dim dwValidFields As Long
Dim dwFlags As Long
'Dim stUTCTime As systemtime
Dim dblLatitude As Double
Dim dblLongitude As Double
Dim flSpeed As Double
Dim flHeading As Double
Dim dblMagneticVariation As Double
Dim flAltitudeWRTSeaLevel As Single
Dim flAltitudeWRTEllipsoid As Single
'GPS_FIX_QUALITY FixQuality;
'GPS_FIX_TYPE FixType;
'GPS_FIX_SELECTION SelectionType;
Dim flPositionDilutionOfPrecision As Single
Dim flHorizontalDilutionOfPrecision As Single
Dim flVerticalDilutionOfPrecision As Single
Dim dwSatelliteCount As Long
Dim rgdwSatellitesUsedPRNs() As Long
Dim dwSatellitesInView As Long
Dim rgdwSatellitesInViewPRNs() As Long
Dim rgdwSatellitesInViewElevation() As Long
Dim rgdwSatellitesInViewAzimuth() As Long
Dim rgdwSatellitesInViewSignalToNoiseRatio() As Long
End Structure
Enum GPS_FIX_QUALITY
GPS_FIX_QUALITY_UNKNOWN
GPS_FIX_QUALITY_GPS
GPS_FIX_QUALITY_DGPS
End Enum
Enum GPS_FIX_TYPE
GPS_FIX_UNKNOWN
GPS_FIX_2D
GPS_FIX_3D
End Enum
Enum GPS_FIX_SELECTION
GPS_FIX_SELECTION_UNKNOWN
GPS_FIX_SELECTION_AUTO
GPS_FIX_SELECTION_MANUAL
End Enum
<StructLayout(LayoutKind.Sequential)> Public Structure SYSTEMTIME
Public wYear As Short
Public wMonth As Short
Public wDayOfWeek As Short
Public wDay As Short
Public wHour As Short
Public wMinute As Short
Public wSecond As Short
Public wMilliseconds As Short
End Structure
Dim gpsHandle As IntPtr = IntPtr.Zero
Public Function OpenGPSDevice() As Boolean
Try
gpsHandle = GPSOpenDevice(Nothing, Nothing, Nothing, 0)
OpenGPSDevice = (gpsHandle <> 0)
MsgBox("Device is open")
Catch ex As Exception
MsgBox("Error opening GPSDevice")
End Try
End Function
Public Function CloseGPSDevice() As Boolean
Try
If gpsHandle = 0 Then Exit Function
GPSCloseDevice(gpsHandle)
gpsHandle = IntPtr.Zero
MsgBox("Device is closed")
Catch ex As Exception
MsgBox("Error closing GPSDevice")
End Try
End Function
Private Sub bmtGPS_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bmtGPS.Click
Dim i As Long
Dim gpsPOS As New GPS_POSITION
Try
'gpsPOS.dwVersion = "GPS_VERSION_1"
'gpsPOS.dwSize = 512
i = GPSGetPosition(gpsHandle, gpsPOS, 500000, 0)
txtTeste.Text &= i
txtTeste.Text &= vbCrLf & "Latitude=" & gpsPOS.dblLatitude
txtTeste.Text &= vbCrLf & "Longitude=" & gpsPOS.dblLongitude
txtTeste.Text &= vbCrLf & "SatelliteCount=" & gpsPOS.dwSatelliteCount
txtTeste.Text &= vbCrLf & "SatellitesInView=" & gpsPOS.dwSatellitesInView
txtTeste.Text &= vbCrLf & "Heading=" & gpsPOS.flHeading
txtTeste.Text &= vbCrLf & "Speed=" & gpsPOS.flSpeed
txtTeste.Text &= vbCrLf & "Flags=" & gpsPOS.dwFlags
Catch ex As Exception
MsgBox("Error getting position")
End Try
End Sub
Private Sub bmtGPSOn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bmtGPSOn.Click
OpenGPSDevice()
End Sub
Private Sub bmtGPSOff_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bmtGPSOff.Click
CloseGPSDevice()
End Sub
Thank your for the GPS Vb.Net Sample
Hi René,
Your sample help me a lot, but I still have some issues and I hope you can give me more clues.
During my tests... everything works fine, but when I tried to use some of the date from LocationChanged, it do not return data. The GPS icon is GREEN, so, it's looks like everything is fine... the Google Maps works with my apps to, but all return ""
frmPrincipal.lblLatitude.Text = e.Position.Longitude.ToString()
frmPrincipal.lblLongitude.Text = e.Position.Longitude.ToString()
frmPrincipal.lblAltitude.Text = e.Position.SeaLevelAltitude.ToString()
Other thing... why at DeviceStateChanged the only way to get data if with a INVOKE like you did?
Invoke(New UpdateDataHandler(AddressOf AddItem), e.DeviceState.FriendlyName)
And final...
As I can see... the LocationChanged, is not so acured... because it was been called every second or less... it's normal?
Best,
Ruben
RStein said:
And here is the project in VB - functional
Click to expand...
Click to collapse
Getting a error with GPS
I'm getting the following error. I get this random, as I read, the GPS API uses a file to get it's info, so... I thing could be it.
gps.GetPosition.SatellitesInViewCount.ToString Run-time exception thrown : System.IO.IOException - The process can not access the file '\Test.txt' because it is being used by another process.
With the Debug, I have the following info:
gps.GetDeviceState.FriendlyName ""
gps.GetDeviceState.DeviceState On {1}
gps.GetDeviceState.ServiceState On {1}
gps.Opened True
And the error showed it self, when I use any of the follow properties:
gps.GetPosition.LatitudeValid
gps.GetPosition.SatelliteCount
gps.GetPosition.Latitude
I saw at my PDA root folder a Test.txt and also I read that file could configured with.
http://msdn.microsoft.com/en-us/library/ms889970.aspx
Some one have any clues?
I'll continue to dig... if I post here if I get more info.
I'm using a Windows Mobile 5 the HP 6945.
With this DLL work on all device????
I made an application named "Where is" and i use the Serial Port to check the info from GPS but in some device i cant get the data and i dont know why.
With this DLL i can resolve all problems?
I work with vb.net.
Wait an answer please.
Bye

[WM6] Disabling taskbar, SIP and hardware keys (including green and red buttons)

Hello there!
I've seen a lot of questions on this topic, and just yesterday, my client asked for this feature implemented in the app that we are currently developing...
After a veeeery intensive and long night, i finally found how to disable all these things! The code is written in c# using .net CF 2.0, and has been tested successfully on a HTC Tynt device. The interesting thing is that it will also disable the End Call and Make Call hardware buttons (VK_TEND and VK_TTALK). If you intend to use this in a production environment you might consider improoving it a little bit.
[DllImport("coredll.dll")]
private static extern bool UnregisterFunc1(KeyModifiers modifiers, int keyID);
[DllImport("coredll.dll", SetLastError = true)]
public static extern bool RegisterHotKey(IntPtr hWnd, // handle to window
int id, // hot key identifier
KeyModifiers Modifiers, // key-modifier options
int key //virtual-key code
);
public enum KeyModifiers
{
None = 0,
Alt = 1,
Control = 2,
Shift = 4,
Windows = 8,
Modkeyup = 0x1000,
}
private void DeactivateUI()
{
try
{
// deactivate the SIP button
IntPtr hSip = FindWindow("MS_SIPBUTTON", "MS_SIPBUTTON");
EnableWindow(hSip, false);
// deactivate the SIP button
IntPtr hTaskBar = FindWindow("HHTaskBar", null);
EnableWindow(hTaskBar, false);
// deactivate the hardware keys
for (Int32 iCounter = 193; iCounter <= 207; iCounter++)
{
UnregisterFunc1(KeyModifiers.Windows, iCounter);
RegisterHotKey(this.Handle, iCounter, KeyModifiers.Windows, iCounter);
}
UnregisterFunc1(KeyModifiers.None, 0x73); //VK_TEND
RegisterHotKey(this.Handle, 0x73, KeyModifiers.None, 0x73);
UnregisterFunc1(KeyModifiers.None, 0x72);
RegisterHotKey(this.Handle, 0x72, KeyModifiers.None, 0x72); //VK_TTALK
}
catch (Exception ex)
{
Log.WriteError(ex, false);
}
}
Cheers!
Very good, helped me a lot! But how do I unlock the keys again, without rebooting?
Thanks!
gciochina said:
Hello there!
I've seen a lot of questions on this topic, and just yesterday, my client asked for this feature implemented in the app that we are currently developing...
After a veeeery intensive and long night, i finally found how to disable all these things! The code is written in c# using .net CF 2.0, and has been tested successfully on a HTC Tynt device. The interesting thing is that it will also disable the End Call and Make Call hardware buttons (VK_TEND and VK_TTALK). If you intend to use this in a production environment you might consider improoving it a little bit.
[DllImport("coredll.dll")]
private static extern bool UnregisterFunc1(KeyModifiers modifiers, int keyID);
[DllImport("coredll.dll", SetLastError = true)]
public static extern bool RegisterHotKey(IntPtr hWnd, // handle to window
int id, // hot key identifier
KeyModifiers Modifiers, // key-modifier options
int key //virtual-key code
);
public enum KeyModifiers
{
None = 0,
Alt = 1,
Control = 2,
Shift = 4,
Windows = 8,
Modkeyup = 0x1000,
}
private void DeactivateUI()
{
try
{
// deactivate the SIP button
IntPtr hSip = FindWindow("MS_SIPBUTTON", "MS_SIPBUTTON");
EnableWindow(hSip, false);
// deactivate the SIP button
IntPtr hTaskBar = FindWindow("HHTaskBar", null);
EnableWindow(hTaskBar, false);
// deactivate the hardware keys
for (Int32 iCounter = 193; iCounter <= 207; iCounter++)
{
UnregisterFunc1(KeyModifiers.Windows, iCounter);
RegisterHotKey(this.Handle, iCounter, KeyModifiers.Windows, iCounter);
}
UnregisterFunc1(KeyModifiers.None, 0x73); //VK_TEND
RegisterHotKey(this.Handle, 0x73, KeyModifiers.None, 0x73);
UnregisterFunc1(KeyModifiers.None, 0x72);
RegisterHotKey(this.Handle, 0x72, KeyModifiers.None, 0x72); //VK_TTALK
}
catch (Exception ex)
{
Log.WriteError(ex, false);
}
}
Cheers!
Click to expand...
Click to collapse
Can u provide the EnableWindow method.I am getting the error in this method
Implement code
Hello!
I have created app to WM 5 - 6.5, but users can close it using END button. I see your code, but i can't implement ( i mean I don't have sufficient knowledge) it to visual studio 2008.
Could you tell me what should I do?
Error 1 'APP.Kiosk' does not contain a definition for 'Handle' and no extension method 'Handle' accepting a first argument of type 'APP.Kiosk' could be found (are you missing a using directive or an assembly reference?) C:\Documents and Settings\lupag\Moje dokumenty\Pobieranie\CEKiosk\CEKiosk\Kiosk.cs 155 43 CEKiosk
Handle? wtf

Categories

Resources