Hello together,
does anyone know why a Notify Icon is shown on Windows Mobile 5.0 Pocket PC's but not shown on Windows Mobile 2003 Pocket PC's?
Here is the code of my Notify Icon class:
Code:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace NotifyClient
{
public class NotifyIcon
{
//Declare click event
public event System.EventHandler Click;
private WindowSink windowSink;
private int uID = 5000;
//Constructor
public NotifyIcon()
{
//Create instance of the MessageWindow subclass
windowSink = new WindowSink(this);
windowSink.uID = uID;
}
//Destructor
~NotifyIcon()
{
Remove();
}
public void Add(IntPtr hIcon)
{
TrayMessage(windowSink.Hwnd, NIM_ADD, (uint)uID, hIcon);
}
public void Remove()
{
TrayMessage(windowSink.Hwnd, NIM_DELETE, (uint)uID, IntPtr.Zero);
}
public void Modify(IntPtr hIcon)
{
TrayMessage(windowSink.Hwnd, NIM_MODIFY, (uint)uID, hIcon);
}
private void TrayMessage(IntPtr hwnd, int dwMessage, uint uID, IntPtr hIcon)
{
NOTIFYICONDATA notdata = new NOTIFYICONDATA();
notdata.cbSize = 152;
notdata.hIcon = hIcon;
notdata.hWnd = hwnd;
notdata.uCallbackMessage = WM_NOTIFY_TRAY;
notdata.uFlags = NIF_MESSAGE | NIF_ICON;
notdata.uID = uID;
int ret = Shell_NotifyIcon(dwMessage, ref notdata);
}
#region API Declarations
internal const int WM_LBUTTONDOWN = 0x0201;
//User defined message
internal const int WM_NOTIFY_TRAY = 0x0400 + 2001;
internal const int NIM_ADD = 0x00000000;
internal const int NIM_MODIFY = 0x00000001;
internal const int NIM_DELETE = 0x00000002;
const int NIF_MESSAGE = 0x00000001;
const int NIF_ICON = 0x00000002;
internal struct NOTIFYICONDATA
{
internal int cbSize;
internal IntPtr hWnd;
internal uint uID;
internal uint uFlags;
internal uint uCallbackMessage;
internal IntPtr hIcon;
//internal char[] szTip = new char[64];
//internal IntPtr szTip;
}
[DllImport("coredll.dll")]
internal static extern int Shell_NotifyIcon(
int dwMessage,ref NOTIFYICONDATA pnid);
[DllImport("coredll.dll")]
internal static extern int SetForegroundWindow(IntPtr hWnd);
[DllImport("coredll.dll")]
internal static extern int ShowWindow(
IntPtr hWnd,
int nCmdShow);
[DllImport("coredll.dll")]
internal static extern IntPtr GetFocus();
#endregion
#region WindowSink
internal class WindowSink : Microsoft.WindowsCE.Forms.MessageWindow
{
//Private members
private int m_uID = 0;
private NotifyIcon notifyIcon;
//Constructor
public WindowSink(NotifyIcon notIcon)
{
notifyIcon = notIcon;
}
public int uID
{
set
{
m_uID = value;
}
}
protected override void WndProc(ref Microsoft.WindowsCE.Forms.Message msg)
{
if (msg.Msg == WM_NOTIFY_TRAY)
{
if((int)msg.LParam == WM_LBUTTONDOWN)
{
if ((int)msg.WParam == m_uID)
{
//If somebody hooked, raise the event
if (notifyIcon.Click != null)
notifyIcon.Click(notifyIcon, null);
}
}
}
}
}
#endregion
}
}
The usage of this class is in my WM 5.0 project identical with my WM 2003 project. But the icon is not shown...
It seems like the space in the "Task Bar" is reserved and my application reacts correct when I click on the place the icon should appear...
Does anyone have an idea?
Greetings
Alex
I am desperately trying to work around some unknown problem caused by our NDIS IM driver on WM6 and HTC TyTn ( TyTn at least, but most likely other devices as well ). I started some other threads regarding different facets of this problem, and no help is coming. Now I am just trying to work around it.
in short the problem is when power events happen the WLAN will never connect.
The work around is programmatically open the control panel with STControlPanel class and press the down button 1 time then the f1 key ( right dash ). This "presses connect" on the last configured access point. This works around my problem, however, I need to detect when the access point has connected. There is a "connecting" and "connected" message for the access point in this control panel dialog ( control panel # 17 ).
My Question: Is there some way to get this text "connecting" or "connected" from the control panel #17?
I have tried wzc, ndisuio, winsock, and other "non control panel" ways to detect connected state, but the IM problem fools all these methods. The only thing I have ever seen that successfully shows when the problem has occurred is the "connecting"/"connected" status in the control panel 17.
Please Help Someone.
p.s. If I can get this worked around, we sell a commercial grade ndis intermediate driver toolkit letting you easily write plugins without any of the hard driver details. We have redirectors, transparent proxy, tunnelers, virtual adapters, lots of good stuff. Also the same plugin will work on all windows desktop platforms vista - 98, WM5/6 and CE and also linux and solaris...
Hello skk
What about notification API?
Here is the solution (simple concept) for Your problem. Interesting parts are in bold.
SNapiTest.cpp
Code:
#include "stdafx.h"
#include "SNapiTest.h"
#include <windows.h>
#include <commctrl.h>
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE g_hInst; // current instance
HWND g_hWndMenuBar; // menu bar handle
[b]
const DWORD WM_WIFISTATUS = WM_USER + 1;
bool g_connecting;
bool g_connected;
HREGNOTIFY g_hNotify;
HREGNOTIFY g_hNotify2;
[/b]
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE, LPTSTR);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
// Perform application initialization:
if (!InitInstance(hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable;
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SNAPITEST));
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SNAPITEST));
wc.hCursor = 0;
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = szWindowClass;
return RegisterClass(&wc);
}
//
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
TCHAR szTitle[MAX_LOADSTRING]; // title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // main window class name
g_hInst = hInstance; // Store instance handle in our global variable
// SHInitExtraControls should be called once during your application's initialization to initialize any
// of the device specific controls such as CAPEDIT and SIPPREF.
SHInitExtraControls();
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_SNAPITEST, szWindowClass, MAX_LOADSTRING);
//If it is already running, then focus on the window, and exit
hWnd = FindWindow(szWindowClass, szTitle);
if (hWnd)
{
// set focus to foremost child window
// The "| 0x00000001" is used to bring any owned windows to the foreground and
// activate them.
SetForegroundWindow((HWND)((ULONG) hWnd | 0x00000001));
return 0;
}
if (!MyRegisterClass(hInstance, szWindowClass))
{
return FALSE;
}
hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
// When the main window is created using CW_USEDEFAULT the height of the menubar (if one
// is created is not taken into account). So we resize the window after creating it
// if a menubar is present
if (g_hWndMenuBar)
{
RECT rc;
RECT rcMenuBar;
GetWindowRect(hWnd, &rc);
GetWindowRect(g_hWndMenuBar, &rcMenuBar);
rc.bottom -= (rcMenuBar.bottom - rcMenuBar.top);
MoveWindow(hWnd, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, FALSE);
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
static SHACTIVATEINFO s_sai;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_HELP_ABOUT:
DialogBox(g_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, About);
break;
case IDM_OK:
SendMessage (hWnd, WM_CLOSE, 0, 0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_CREATE:
SHMENUBARINFO mbi;
memset(&mbi, 0, sizeof(SHMENUBARINFO));
mbi.cbSize = sizeof(SHMENUBARINFO);
mbi.hwndParent = hWnd;
mbi.nToolBarId = IDR_MENU;
mbi.hInstRes = g_hInst;
if (!SHCreateMenuBar(&mbi))
{
g_hWndMenuBar = NULL;
}
else
{
g_hWndMenuBar = mbi.hwndMB;
}
// Initialize the shell activate info structure
memset(&s_sai, 0, sizeof (s_sai));
s_sai.cbSize = sizeof (s_sai);
[b]
g_connecting = false;
g_connected = false;
{HRESULT hr = RegistryNotifyWindow(SN_WIFISTATECONNECTING_ROOT,
SN_WIFISTATECONNECTING_PATH, SN_WIFISTATECONNECTING_VALUE,
hWnd, WM_WIFISTATUS, 0, NULL, &g_hNotify);}
{HRESULT hr2 = RegistryNotifyWindow(SN_WIFISTATECONNECTING_ROOT,
SN_WIFISTATECONNECTED_PATH, SN_WIFISTATECONNECTED_VALUE,
hWnd, WM_WIFISTATUS, 0, NULL, &g_hNotify2);}
[/b]
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
[b]
case WM_WIFISTATUS:
{
DWORD newValue = (DWORD) wParam;
WCHAR caption[] = L"Wifi Status";
if ((newValue & SN_WIFISTATECONNECTED_BITMASK) == SN_WIFISTATECONNECTED_BITMASK)
{
if (!g_connected)
{
g_connected = true;
g_connecting = false;
MessageBox(hWnd, L"Connected!!", caption, MB_OK);
}
break;
}
if ((newValue & SN_WIFISTATECONNECTING_BITMASK) == SN_WIFISTATECONNECTING_BITMASK)
{
if (!g_connecting)
{
g_connecting = true;
g_connected =false;
MessageBox(hWnd, L"Connecting...", caption, MB_OK);
}
}
break;
}
[/b]
case WM_DESTROY:
CommandBar_Destroy(g_hWndMenuBar);
[B]
RegistryCloseNotification(g_hNotify);
RegistryCloseNotification(g_hNotify2);
[/B]
PostQuitMessage(0);
break;
case WM_ACTIVATE:
// Notify shell of our activate message
SHHandleWMActivate(hWnd, wParam, lParam, &s_sai, FALSE);
break;
case WM_SETTINGCHANGE:
SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
// Create a Done button and size it.
SHINITDLGINFO shidi;
shidi.dwMask = SHIDIM_FLAGS;
shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN | SHIDIF_EMPTYMENU;
shidi.hDlg = hDlg;
SHInitDialog(&shidi);
}
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
case WM_CLOSE:
EndDialog(hDlg, message);
return TRUE;
}
return (INT_PTR)FALSE;
}
Needed includes:
// TODO: reference additional headers your program requires here
#include <snapi.h>
#include <regext.h>
snapi.h
Thank you so much for your post. I just found snapi.h, I assume this is snapitest.h?
IT WORKS!
It works! You are my hero RStein. You are a god among men.
Great. ) Thanks for sharing the results.
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
With this code:
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace TEST1
{
public partial class Form1 : Form
{
public delegate void RILRESULTCALLBACK(int dwCode, IntPtr hrCmdID, IntPtr lpData, int cbData, int dwParam);
public delegate void RILNOTIFYCALLBACK(int dwCode, IntPtr lpData, int cbData, int dwParam);
public static IntPtr hRil;
[StructLayout(LayoutKind.Explicit)]
class RILADDRESS
{
[FieldOffset(0)]
public uint dwSize;
[FieldOffset(4)]
public uint dwParams;
[FieldOffset(8)]
public uint dwType;
[FieldOffset(12)]
public uint dwNumPlan;
[FieldOffset(16)]
public byte[] sAddress = new byte[256 * 2];
//[FieldOffset(528)]
}
[StructLayout(LayoutKind.Explicit)]
class RILSUBADDRESS
{
[FieldOffset(0)]
public uint dwSize;
[FieldOffset(4)]
public uint dwParams;
[FieldOffset(8)]
public uint dwType;
[FieldOffset(12)]
public byte[] sSubAddress = new byte[256 * 2];
//[FieldOffset(524)]
}
[StructLayout(LayoutKind.Explicit)]
class RILREMOTEPARTYINFO
{
[FieldOffset(0)]
public uint dwSize;
[FieldOffset(4)]
public uint dwParams;
/*[FieldOffset(8)]
public RILADDRESS rilAddress = new RILADDRESS();
[FieldOffset(536)]
public RILSUBADDRESS rilSubAddress = new RILSUBADDRESS();
[FieldOffset(1060)]
public char[] sDescription = new char[256 * 2];
[FieldOffset(1572)]
public uint dwValidity;*/
}
[StructLayout(LayoutKind.Explicit)]
class RILCELLTOWERINFO
{
[FieldOffset(0)]
uint dwSize;
[FieldOffset(4)]
uint dwParams;
[FieldOffset(8)]
public uint dwMobileCountryCode;
[FieldOffset(12)]
public uint dwMobileNetworkCode;
[FieldOffset(16)]
public uint dwLocationAreaCode;
[FieldOffset(20)]
public uint dwCellID;
[FieldOffset(24)]
uint dwBaseStationID;
[FieldOffset(28)]
uint dwBroadcastControlChannel;
[FieldOffset(32)]
uint dwRxLevel;
[FieldOffset(36)]
uint dwRxLevelFull;
[FieldOffset(40)]
uint dwRxLevelSub;
[FieldOffset(44)]
uint dwRxQuality;
[FieldOffset(48)]
uint dwRxQualityFull;
[FieldOffset(52)]
uint dwRxQualitySub;
/* More minor interesting fields below */
}
[StructLayout(LayoutKind.Explicit)]
class RILRINGINFO
{
[FieldOffset(0)]
public uint dwSize;
[FieldOffset(4)]
public uint dwParams;
[FieldOffset(8)]
public uint dwCallType;
[FieldOffset(12)]
public uint dwAddressID;
}
//private static bool done = false;
private static string result = "";
[DllImport("ril.dll")]
private static extern IntPtr RIL_Initialize(int dwIndex, RILRESULTCALLBACK pfnResult, RILNOTIFYCALLBACK pfnNotify, int dwNotificationClasses, int dwParam, out IntPtr lphRil);
[DllImport("ril.dll", EntryPoint = "RIL_GetCellTowerInfo")]
private static extern IntPtr RIL_GetCellTowerInfo(IntPtr hRil);
[DllImport("ril.dll", EntryPoint = "RIL_Hangup")]
private static extern IntPtr RIL_Hangup(IntPtr hRil);
[DllImport("ril.dll")]
private static extern IntPtr RIL_Deinitialize(IntPtr hRil);
public static void f_notify(int dwCode, IntPtr lpData, int cbData, int dwParam)
{
string strMsg = "";
switch (dwCode & 0x00ff0000) //RIL_NCLASS_ALL
{
case 0x00080000: //RIL_NCLASS_SUPSERVICE
switch (dwCode & 0xff)
{
case 0x00000001: // RIL_NOTIFY_CALLERID
RILREMOTEPARTYINFO rilRemotePartyInfo = new RILREMOTEPARTYINFO();
Marshal.PtrToStructure(lpData, rilRemotePartyInfo);
break;
case 0x00000002: // RIL_NOTIFY_DIALEDRID
break;
case 0x00000003: // RIL_NOTIFY_CALLWAITING
break;
case 0x00000004: // RIL_NOTIFY_SUPSERVICEDATA
break;
}
strMsg += "SUPSERVICE";
break;
case 0x00010000: //RIL_NCLASS_CALLCTRL
switch (dwCode & 0xff)
{
case 0x00000001: // RIL_NOTIFY_RING
RILRINGINFO rilRingInfo = new RILRINGINFO();
Marshal.PtrToStructure(lpData, rilRingInfo);
switch (rilRingInfo.dwCallType)
{
case 0x00000000:
strMsg += "UNKNOWN ";
break;
case 0x00000001:
strMsg += "VOICE ";
//RIL_Hangup(hRil);
break;
case 0x00000002:
strMsg += "DATA ";
break;
case 0x00000003:
strMsg += "FAX ";
break;
default:
strMsg += "UNHANDLED ";
break;
}
break;
case 0x00000002: // RIL_NOTIFY_CONNECT
strMsg += "CONNECT ";
break;
case 0x00000003: // RIL_NOTIFY_DISCONNECT
strMsg += "DISCONNECT ";
break;
case 0x0000000B: // RIL_NOTIFY_CALLPROGRESSINFO
strMsg += "CPI ";
break;
default:
strMsg += "SOME ";
break;
}
strMsg += "CALL";
break;
case 0x00020000: // RIL_NCLASS_MESSAGE
switch (dwCode & 0xff)
{
case 0x00000001: // RIL_NOTIFY_MESSAGE
strMsg += "NEW ";
break;
default:
strMsg += "SOME ";
break;
}
strMsg += "SMS";
break;
}
//MessageBox.Show(strMsg);
}
public static void f_result(int dwCode, IntPtr hrCmdID, IntPtr lpData, int cbData, int dwParam)
{
/*RILCELLTOWERINFO rci = new RILCELLTOWERINFO();
Marshal.PtrToStructure(lpData, rci);
result = String.Format("MCC: {0}, MNC: {1}, LAC: {2}, CID: {3}",
rci.dwMobileCountryCode,
rci.dwMobileNetworkCode,
rci.dwLocationAreaCode,
rci.dwCellID);
done = true;*/
}
public static string GetCellTowerInfo()
{
IntPtr res;
RILRESULTCALLBACK result = new RILRESULTCALLBACK(f_result);
RILNOTIFYCALLBACK notify = new RILNOTIFYCALLBACK(f_notify);
res = RIL_Initialize(1, result, notify, (0x00010000 | 0x00020000 | 0x00080000), 0, out Form1.hRil);
if (res != IntPtr.Zero)
return ("Could not initialize Ril");
/*Form1.done = false;
Form1.result = "";
res = RIL_GetCellTowerInfo(hRil);
int i = 10;
while (i-- > 0 && !Form1.done)
{
System.Threading.Thread.Sleep(1000);
}
RIL_Deinitialize(hRil);*/
return Form1.result;
}
public Form1()
{
InitializeComponent();
string s = Form1.GetCellTowerInfo();
//MessageBox.Show(s);
}
private void button1_Click(object sender, EventArgs e)
{
RIL_Deinitialize(hRil);
Application.Exit();
}
}
}
at line 136 (Marshal.PtrToStructure(lpData, rilRemotePartyInfo) there is an exception (NotSupportedException) and i don't understand why!!!
Need some help please...........
As what was stated on the header I want to implement either a "paint" function for user to edit paint/censor unwanted parts of a photo displayed on a imageview before uploading it to a server in the edited format and a redo function if user makes a mistake while editing?
How do I come about doing it, I've read relevant topics on Canvas, or FingerPaint but still puzzled on how to implement it based on my project here? Tried referencing to the links here and here but without success in implementing the codes into my project code due to my lack of programming skills.
Thanks for any help rendered!
Tried integrating the codes below into my code above (image preview after taking a photo with the camera) for user to start editing via painting but still not working? Thanks for any help rendered!
Code:
public class Drawing extends View {
private Paint mPaint, mBitmapPaint;
Intent intent = getIntent();
Bitmap mBitmap = (Bitmap) intent.getParcelableExtra("BitmapImage");
private Canvas mCanvas;
private Path mPath;
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
private int color, size, state;
private ArrayList<Path> paths = new ArrayList<Path>();
private ArrayList<Path> undonePaths = new ArrayList<Path>();
private ArrayList<Integer> colors = new ArrayList<Integer>();
private ArrayList<Integer> sizes = new ArrayList<Integer>();
public Drawing(Context c) {
super(c);
}
public Drawing(Context c,int width, int height, int size, int color, int state) {
super(c);
mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mPath = new Path();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
// mBitmapPaint = new Paint(Paint.DITHER_FLAG);
// mBitmapPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
setColor(color);
setSize(size);
setState(state);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected void onDraw(Canvas canvas) {
// canvas.drawColor(Color.TRANSPARENT);
// canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
//
// if (state == 0)
// mBitmap.eraseColor(Color.TRANSPARENT);
for (int i = 0; i < paths.size(); i++) {
mPaint.setColor(colors.get(i));
mPaint.setStrokeWidth(sizes.get(i));
canvas.drawPath(paths.get(i), mPaint);
}
mPaint.setColor(color);
mPaint.setStrokeWidth(size);
canvas.drawPath(mPath, mPaint);
}
public void setColor(int color) {
this.color = color;
}
public void setSize(int size) {
this.size = size;
}
public void setState(int state) {
this.state = state;
// if (state == 0)
// mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
// else
// mPaint.setXfermode(null);
}
public void onClickUndo() {
if (paths.size() > 0) {
undonePaths.add(paths.remove(paths.size() - 1));
sizes.remove(sizes.size() - 1);
colors.remove(colors.size() - 1);
invalidate();
}
}
private void touch_start(float x, float y) {
undonePaths.clear();
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
mCanvas.drawPath(mPath, mPaint);
colors.add(color);
sizes.add(size);
paths.add(mPath);
mPath = new Path();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}