Best all,
A while ago I tried to make a simple application which can export all my smses and mmses to my local database server. It runs quite smoothly but I can't manage to get the correct mms body data. It seems that about 5% of the exported body data(for example a sent picture in jpeg format) is different from the original jpeg picture/body data: the exported picture data can't be viewed, it is corrupt.
I suspect the method of exporting the data must be changed from string to binary, but I don't know exactly how to proceed.
I'm using C# 2008 in combination with the MAPIdotnet library, and my target device is a HTC HD Mini with Windows Mobile 6.5 professional.
The part of my code where it's going wrong:
Code:
ASCIIEncoding asen = new ASCIIEncoding();
byte[] ba = asen.GetBytes(s);
bw.Write(ba);
bw.Close();
fs.Close();
if (messages[msgID].Body != null)
{
FileStream fs2 = File.Create("\\Opslagkaart\\Debug\\body_" + Convert.ToString(msgID) + ".dat");
BinaryWriter bw2 = new BinaryWriter(fs2);
System.Text.UnicodeEncoding enc = new System.Text.UnicodeEncoding();
byte[] file = enc.GetBytes(messages[msgID].Body);
//bw2.Write(messages[msgID].Body);
bw2.Write(file);
bw2.Close();
fs2.Close();
}
In combination with MAPIdotnet's code:
Code:
public string Body
{
get
{
IStreamChar s = (IStreamChar)this.msg.OpenProperty(cemapi.PropTags.PR_BODY, 0);
if (s == null)
return "";
IntPtr p = Marshal.AllocHGlobal(4);
char[] b = new char[3];
StringBuilder str = new StringBuilder();
int c, len = b.Length * 2;
do
{
s.Read(b, len, p);
c = Marshal.ReadInt32(p);
str.Append(new string(b, 0, c / 2));
}
while (c >= len);
Marshal.FreeHGlobal(p);
return str.ToString();
}
}
Can somebody give a hint of how to proceed?
Thanks,
I suddenly got some more inspiration and, with help from google, I've managed to correctly retrieve the binary jpeg attachments of two of my mmses.
The code part of my program:
Code:
//if (messages[msgID].BodyBinary.Length>0)
//{
FileStream fs2 = File.Create("\\Opslagkaart\\Debug\\body_" + Convert.ToString(msgID) + ".dat");
BinaryWriter bw2 = new BinaryWriter(fs2);
bw2.Write(messages[msgID].BodyBinary);
bw2.Close();
fs2.Close();
//}
The code part of the customized MAPIdotnet:
Code:
private static IntPtr ReadBuffer;
static int Read(OpenNETCF.Runtime.InteropServices.ComTypes.IStream strm, byte[] buffer)
{
if (ReadBuffer == IntPtr.Zero) ReadBuffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(int)));
try
{
strm.Read(buffer, buffer.Length, ReadBuffer);
}
catch (NullReferenceException e)
{
//do nothing
}
return Marshal.ReadInt32(ReadBuffer);
}
public byte[] BodyBinary
{
get
{
int buffsize = 1024*1024*2; /* If mms body is bigger than 2MB we have a problem here */
byte[] buffer = new byte[buffsize];
Read(this.msg.OpenProperty(cemapi.PropTags.PR_BODY, 0), buffer);
byte[] data = buffer;//ms.ToArray();
Marshal.FreeCoTaskMem(ReadBuffer);
return data;
}
}
But now ALL bodies are saved as 2MB files.. including the empty ones from for example a sms. And not all mms bodies are of the max size of 2mb. My carrier/phone supports up to 1MB. Perhaps I need to get some 'dynamic size' buffer instead of the fixed one. Does anyone have an idea on how to determine the size of the
this.msg.OpenProperty(cemapi.PropTags.PR_BODY, 0)
Click to expand...
Click to collapse
stream ?
I've solved all my problems by means of the following code (for mapidotnet):
Code:
private static IntPtr ReadBuffer;
static int Read(OpenNETCF.Runtime.InteropServices.ComTypes.IStream strm, byte[] buffer)
{
int returnvalue = 0;
if (ReadBuffer == IntPtr.Zero) ReadBuffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(int)));
try
{
strm.Read(buffer, buffer.Length, ReadBuffer);
returnvalue = Marshal.ReadInt32(ReadBuffer);
}
catch (NullReferenceException e)
{
returnvalue = 0;
}
return returnvalue;
}
public byte[] BodyBinary
{
get
{
int newdatasize = 0;
int buffsize = 1024*1024*3; /* If mms body is bigger than 3MB we have a problem here */
byte[] buffer = new byte[buffsize];
newdatasize = Read(this.msg.OpenProperty(cemapi.PropTags.PR_BODY, 0), buffer);
if (newdatasize < 0) { newdatasize = 0; }
byte[] data = new byte[newdatasize];
Buffer.BlockCopy(buffer, 0, data, 0, newdatasize);
Marshal.FreeCoTaskMem(ReadBuffer);
return data;
}
}
Now all is working fine and the exported files are of their own real size. I'm sure the above code can be optimized but it's working good now.
Related
I'm looking for a way to turn off the data (GRPS)
Search didn't brought me anything usefull, I'm sure there is somwhere the data but can't find it.
I'm especially need it for WM 6.5 (HD2)
Search around for Modaco's NoData program. It's late and I'm too tired to search it up for you right now.
kekkle said:
Search around for Modaco's NoData program. It's late and I'm too tired to search it up for you right now.
Click to expand...
Click to collapse
Thanks for the replay but it’s not what I meant, sorry for not be clarify.
I know the NoData app and actually i just finish writing something similar but more user friendly, hope to release it asap (Now I have problem with the icon )
What I’m looking is a way to turn off programmatically the data connection of the device, what the CommManager in the HTC sense do.
I tried to use the RAS api but it didn't work
look for jmlcomm.exe here at xda and use it in your app.simple command line call.and free to use.
MichelDiamond said:
look for jmlcomm.exe here at xda and use it in your app.simple command line call.and free to use.
Click to expand...
Click to collapse
Thanks for the idea, I'll try it.
But I prefer to do it directly from my app. without calling external tool.
I found a solution!
Its from few posts in the net, don't remember where exactly with some modification of me.
here is the code I use, if someone else will need it:
Code:
using System;
using System.Text;
using System.Runtime.InteropServices;
namespace RasHelper
{
class RasHelper
{
private const int SUCCESS = 0;
private const int ERROR_NOT_ENOUGH_MEMORY = 8;
private const int RASBASE = 600;
private const int ERROR_BUFFER_TOO_SMALL = RASBASE + 3;
private const int ERROR_INVALID_SIZE = RASBASE + 32;
// --- RASCONN data structure definition (refer to ras.h) --
private const int RAS_MaxEntryName = 20;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct RASCONN
{
public int dwSize;
public IntPtr hrasconn;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxEntryName + 1)]
public string szEntryName;
}
// --------------------------------------------
[DllImport("coredll.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern uint RasEnumConnections(
[In, Out] RASCONN[] rasconn,
[In, Out] ref int cb,
[Out] out int connections);
[DllImport("coredll.dll")]
private static extern uint RasHangUp(IntPtr pRasConn);
/// <summary>
/// Returns all active RAS connections as an array of data structure RASCONN
/// </summary>
/// <returns></returns>
public static RASCONN[] GetAllConnections()
{
RASCONN[] tempConn = new RASCONN[1];
RASCONN[] allConnections = tempConn;
tempConn[0].dwSize = Marshal.SizeOf(typeof(RASCONN));
int lpcb = tempConn[0].dwSize;
int lpcConnections = 0;
uint ret = RasEnumConnections(tempConn, ref lpcb, out lpcConnections);
if (ret == ERROR_INVALID_SIZE)
{
throw new Exception("RAS: RASCONN data structure has invalid format");
}
else if (ret == ERROR_BUFFER_TOO_SMALL && lpcb != 0)
{
// first call returned that there are more than one connections
// and more memory is required
allConnections = new RASCONN[lpcb / Marshal.SizeOf(typeof(RASCONN))];
allConnections[0] = tempConn[0];
ret = RasEnumConnections(allConnections, ref lpcb, out lpcConnections);
}
// Check errors
if (ret != SUCCESS)
{
throw new Exception("RAS returns error: " + ret);
}
if (lpcConnections > allConnections.Length)
{
throw new Exception("RAS: error retrieving correct connection count");
}
else if (lpcConnections == 0)
{
// if there are no connections resize the data structure
allConnections = new RASCONN[0];
}
return allConnections;
}
/// <summary>
/// Closes all active RAS connections
/// </summary>
/// <returns></returns>
public static void CloseAllConnections()
{
RASCONN[] connections = GetAllConnections();
for (int i = 0; i < connections.Length; ++i)
{
//MessageBox.Show(connections[i].ToString());
RasHangUp(connections[i].hrasconn);
}
}
/// <summary>
/// Check if there are open data connections
/// </summary>
/// <returns></returns>
public static bool IsConnectionsOpen()
{
RASCONN[] connections = GetAllConnections();
if (connections.Length > 0)
return true;
else
return false;
}
}
}
how do i replicate this under windows mobile. The first function works flawlessly however the second version (Which is required to run on windows mobile 6.1-6.5) doesn't.. If anyone has any idea how to fix it i'm willing to try it out.
Thanks
Code:
private static byte[] WebPost(string url, byte[] data)
{
var webClient = new WebClient();
return webClient.UploadData(url, data);
}
This dont.
Code:
private static byte[] WebPost(string url, byte[] data)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Credentials = System.Net.CredentialCache.DefaultCredentials;
request.Timeout = 10000; // 10 secs
request.Method = "POST";
byte[] requestPostBuffer = System.Text.Encoding.GetEncoding(1252).GetBytes(ByteArrayToStr(data));
request.ContentLength = requestPostBuffer.Length;
Stream requestPostData = request.GetRequestStream();
requestPostData.Write(requestPostBuffer, 0, requestPostBuffer.Length);
requestPostData.Close();
// initialize the httpweresponse object
HttpWebResponse webResponse = (HttpWebResponse)request.GetResponse();
// set our encoding
Encoding enc = System.Text.Encoding.GetEncoding(1252);
//initialis the webresponse stream with our encoding
StreamReader webResponseStream = new StreamReader(webResponse.GetResponseStream(),enc);
// create a string to copy it all into.
string streamedData = webResponseStream.ReadToEnd();
webResponse.Close();
webResponseStream.Close();
byte[] convertedResponse = StrToByteArray(streamedData);
convertedResponse = Encoding.Convert(System.Text.Encoding.Default, Encoding.GetEncoding(1252),convertedResponse);
return convertedResponse;
}
hello! i hope this is the right forum for my request.
i`ve tried to hack some files from JS2, which supports national roaming without data roaming enabled, into the deodexed JVK framework.jar. the result was crashing com.....phone and no working phone function.
here are the outputs of jd-gui after i used dex2jar on services.dex in framework.jar for com/android/internal/telephony/gsm/GsmServiceStateTracker.class with the relevant code:
JS2:
PHP:
private boolean isRoamingBetweenOperators(boolean paramBoolean, ServiceState paramServiceState)
{
String str1 = SystemProperties.get("gsm.sim.operator.alpha", "empty");
String str2 = paramServiceState.getOperatorAlphaLong();
String str3 = paramServiceState.getOperatorAlphaShort();
int i;
if (str2 != null)
{
String str4 = str1;
String str5 = str2;
if (str4.equals(str5))
i = 1;
}
while (true)
{
int j;
label72: String str8;
String str9;
int k;
label141: int m;
int n;
int i1;
if (str3 != null)
{
String str6 = str1;
String str7 = str3;
if (str6.equals(str7))
{
j = 1;
str8 = SystemProperties.get("gsm.sim.operator.numeric", "");
str9 = paramServiceState.getOperatorNumeric();
if ((str8 == null) || (str9 == null))
break label318;
String str10 = str8;
String str11 = "24421";
if (!str10.equals(str11))
break label318;
String str12 = str9;
String str13 = "24405";
if (!str12.equals(str13))
break label318;
k = 1;
m = 1;
n = 0;
i1 = 3;
}
}
try
{
String str14 = str8;
int i2 = n;
int i3 = i1;
String str15 = str14.substring(i2, i3);
String str16 = str9;
int i4 = 0;
int i5 = 3;
String str17 = str16.substring(i4, i5);
int i6 = str15.equals(str17);
m = i6;
label208: String[] arrayOfString1 = this.phone.mSIMRecords.getFakeHomeOn();
int i8;
if (arrayOfString1 != null)
{
String[] arrayOfString2 = arrayOfString1;
int i7 = arrayOfString2.length;
i8 = 0;
label237: if (i8 < i7)
{
String str18 = arrayOfString2[i8];
if (!str18.equals(str9))
{
String str19 = str9;
int i9 = 0;
int i10 = 3;
String str20 = str19.substring(i9, i10);
String str21 = str18;
String str22 = str20;
if (!str21.equals(str22));
}
else
{
n = 0;
}
}
}
while (true)
{
return n;
i = 0;
break;
j = 0;
break label72;
label318: k = 0;
break label141;
i8 += 1;
break label237;
StringBuilder localStringBuilder = new StringBuilder().append("isRoamingBetweenOperators : equalsSaunalahtiElisa=");
int i11 = k;
String str23 = i11;
int i12 = Log.w("GSM", str23);
if (SIMRecords.isNationalRoaming(str8, str9))
{
n = 0;
continue;
}
if ((paramBoolean) && ((m == 0) || ((i == 0) && (j == 0))) && (k == 0))
{
n = 1;
continue;
}
n = 0;
}
}
catch (Exception localException)
{
break label208;
}
}
}
http://pastebin.com/stD1YFPB
JVK:
PHP:
private boolean isRoamingBetweenOperators(boolean paramBoolean, ServiceState paramServiceState)
{
String str1 = SystemProperties.get("gsm.sim.operator.alpha", "empty");
String str2 = paramServiceState.getOperatorAlphaLong();
String str3 = paramServiceState.getOperatorAlphaShort();
int i;
if ((str2 != null) && (str1.equals(str2)))
i = 1;
while (true)
{
int j;
label56: String str4;
String str5;
int k;
int m;
int n;
if ((str3 != null) && (str1.equals(str3)))
{
j = 1;
str4 = SystemProperties.get("gsm.sim.operator.numeric", "");
str5 = paramServiceState.getOperatorNumeric();
k = 1;
m = 0;
n = 3;
}
try
{
String str6 = str4;
int i1 = m;
int i2 = n;
String str7 = str6.substring(i1, i2);
String str8 = str5;
int i3 = 0;
int i4 = 3;
String str9 = str8.substring(i3, i4);
int i5 = str7.equals(str9);
k = i5;
label140: String[] arrayOfString1 = this.phone.mSIMRecords.getFakeHomeOn();
int i7;
if (arrayOfString1 != null)
{
String[] arrayOfString2 = arrayOfString1;
int i6 = arrayOfString2.length;
i7 = 0;
label169: if (i7 < i6)
{
String str10 = arrayOfString2[i7];
if (!str10.equals(str5))
{
String str11 = str5;
int i8 = 0;
int i9 = 3;
String str12 = str11.substring(i8, i9);
String str13 = str10;
String str14 = str12;
if (!str13.equals(str14));
}
else
{
m = 0;
}
}
}
while (true)
{
return m;
i = 0;
break;
j = 0;
break label56;
i7 += 1;
break label169;
if ((paramBoolean) && ((k == 0) || ((i == 0) && (j == 0))))
{
m = 1;
continue;
}
m = 0;
}
}
catch (Exception localException)
{
break label140;
}
}
}
http://pastebin.com/mgNYbWPa
you can see in the code of JS2 there is some code with "isNationalRoaming" which in JVK does not exist. i think this is the reason why national roaming without data roaming enabled is not working in JVK (and also many other sgs roms). i`ve tried to swap the JS2 GsmServiceStateTracker.smali file into the JVK framework, smali it back to .dex and put services.dex back into framework.jar with 7zip. the result was no working com...phone.
i`m no pro, so i think i did something wrong and some of you pro devs maybe have the answer how to do this. many users with virtual network operators like hutchison 3, bob, yesss, and many more would be happy if there will be a way without enabling the risky dataroaming, which could be very expensive when you are geting near a frontier and using data from foreign countries.
push
unwanted data roaming could be really expensive, please help. a lot of users would love you for a working solution! i would donate some beers for a working howto/fix!
to all MVNO users like 3, bob, yesss, .... push this thread with your comments how you would love national roaming without the risk of high costs in the near of frontiers!
I think solution could be easier
Who is your mobile provider?
BOB in austria, MVNO in a1 network.
bob: at 23211
a1: at 23201
Extract this file, paste 'spn-conf.xml' on system/etc/ and reboot
Let me know if it works!
IT WORKS! THANX DUDE!
here are the promised beers: 9J3661079T435484J
Glad tit worked!
Many thanks for your beer!
rafalense said:
Glad tit worked!
Many thanks for your beer!
Click to expand...
Click to collapse
Should this file also work for the Desire (Provider= 3 Austria)
Greetings
r u schnello from braunau?
i think it should work. if u have root, try it.
if it doesn`t work, delete the file again. it won`t harm anything.
edit: the fake_home data for 3 isn`t in the file. i will try to find some more infos about 3 roaming.
paratox said:
r u schnello from braunau?
i think it should work. if u have root, try it.
if it doesn`t work, delete the file again. it won`t harm anything.
Click to expand...
Click to collapse
Thx for the quick reply,
yeah my home town is braunau.
Greetings
Schnello said:
Thx for the quick reply,
yeah my home town is braunau.
Greetings
Click to expand...
Click to collapse
you`ve got a pm!
if we find a solution, we will post it here.
Could this also work on a stock nexus one with gingerbread?
Hello,
i started to wrote my first WO7 applicatin.
I got following code:
Code:
private void BtnStart_Click(object sender, RoutedEventArgs e)
{
BtnStart.Content = "Calculating...";
for (int i = 0; i < Pb1.Maximum; i++)
{
...
}
...
}
My Problem is that the content of the Button doesn't change to "Calculating". Even my Progressbar:
Code:
private void PbStep()
{
if (Pb1.Value == Pb1.Maximum)
{
Pb1.Value = 0;
MessageBox.Show("Progressbar Overflow");
}
else
{
Pb1.Value = Pb1.Value + 1;
}
}
It is wrapped in s loop, and the bar begins with 0 and then switsch to 100%, but i cant see the steps between.
I think i need a refresh command. in visual basic it is Me.Update();.
I tried many codes from google, but nothing helped. I hope some1 can help me.
many thank
Try
Code:
Dispatcher.BeginInvoke(() =>
{
BtnStart.Content = "Calculating...";
});
i did already try this. but now when i press the button, while calculation nothing happens, and after the calculation is finished, the button content changes to "calculating" and don't changes back to "start".
so i put the code in both parts and now i got the same as before. the button did not change its content
Code:
private void BtnStart_Click(object sender, RoutedEventArgs e)
{
LblDuration.Text = "";
Dispatcher.BeginInvoke(() =>
{
BtnStart.Content = "Calculating...";
});
Pb1.Value = 0.0;
Pb1.Maximum = Max;
DateTime StartZeit = DateTime.Now;
for (int i = 0; i < Pb1.Maximum; i++)
{
PbStep();//Count Up PorgressBar
}
DateTime EndZeit = DateTime.Now;
TimeSpan GemesseneZeit = EndZeit - StartZeit;
LblDuration.Text = "Duration: " + GemesseneZeit.ToString();
Dispatcher.BeginInvoke(() =>
{
BtnStart.Content = "Start";
});
}
private void PbStep()
{
try
{
Pb1.Value = Pb1.Value + 1;
}
catch
{
Pb1.Value = 0;
MessageBox.Show("Progressbar Overflow");
}
}
But thank you for your help. any other ideas?
you really need to be looking at a background thread (background worker control may allow you do do this)
any tight loop like that will freeze the UI until the loop has finished
in the 'old days' a doevents within the loop itself would have been suffice but this is not good practice
HTH
Try this one, it does what you've trying to implement but using a correct way:
Code:
using System.Windows.Threading;
private void BtnStart_Click(object sender, RoutedEventArgs e)
{
BtnStart.Content = "Calculating...";
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(100);
timer.Tick += (_, __) =>
{
// Here is replacement of your PbStep()
Pb1.Value++;
};
timer.Start();
}
i got it now this way:
Code:
private void BtnStart_Click(object sender, RoutedEventArgs e)
{
LblDuration.Text = "Duration: Calculating...";
BtnStart.Content = "Wait";
DateTime StartZeit = DateTime.Now;
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(1);
timer.Tick += (_, __) =>
{
for (int i = 0; i < Pb1.Maximum; i++)
{
Pb1.Value++;
}
timer.Stop();
LblDuration.Text = "Duration: " + (DateTime.Now - StartZeit).ToString();
BtnStart.Content = "Start";
};
timer.Start();
}
It is half working. When i press Start, the button changes its content imediatly and after finishing the loop it return to its default content.
now i got 2 problems:
1. the progressbar isnt smooth jet
and the bigger one:
2. i wanted to create a benchmark programm an measure how long it takes to count a progressbar from 0 to 1million. now with the timer i dont have the real cpu speed because it is always waiting for the timer to tick. so the benchmark is sensless
@ cameronm:
I know the DoEvent command from other languages, but i wans able to use this in c#. i mainly programm in visual basic, cause this seems to be easy (In this case i would use Me.Update). I have heard from the Background worker, but never tried it. Maybe this can help.
I will do some google search and try to use the Background worker. I'll post again if i got new code
Thanks you all !
hello again
im now that far:
Code:
public partial class MainPage : PhoneApplicationPage
{
//Globale Variablen
private BackgroundWorker bw = new BackgroundWorker();
public int Max = 0;
// Konstruktor
public MainPage()
{
InitializeComponent();
Max = 500000;
bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
}
private void BtnStart_Click(object sender, RoutedEventArgs e)
{
if (bw.IsBusy != true)
{
LblDuration.Text = "";
BtnStart.Content = "Calculating...";
Pb1.Value = 0.0;
Pb1.Maximum = Max;
bw.RunWorkerAsync();
}
}
private void BtnStop_Click(object sender, System.Windows.RoutedEventArgs e)
{
if (bw.WorkerSupportsCancellation == true)
{
bw.CancelAsync();
}
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
DateTime StartZeit = DateTime.Now;
//Failure by any deklarion
//like int i = 0 or BtnStart.Content = "Calculating...";
for (int i = 0; i < Pb1.Maximum; i++)
{
if ((worker.CancellationPending == true)) //Abbruchbedingung
{
e.Cancel = true;
break;
}
else //Progressbedingung
{
PbStep();//Count Up PorgressBar
}
}
DateTime EndZeit = DateTime.Now;
TimeSpan GemesseneZeit = EndZeit - StartZeit;
LblDuration.Text = "Duration: " + GemesseneZeit.ToString();
BtnStart.Content = "Start";
}
private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if ((e.Cancelled == true))
{
this.LblStatus.Text = "Canceled!";
}
else if (!(e.Error == null))
{
this.LblStatus.Text = ("Error: " + e.Error.Message);
}
else
{
this.LblStatus.Text = "Done!";
}
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.LblPercentage.Text = (e.ProgressPercentage.ToString() + "%");
}
private void PbStep()
{
try
{
Pb1.Value = Pb1.Value + 1;
}
catch
{
Pb1.Value = 0;
MessageBox.Show("Progressbar Overflow");
}
}
In the DoWork Function i receive an error when i try to set a variable like int i=0.
The Failure:UnauthorizedAccessException: Invalid cross-thread access
i followed this instruction: http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx
but there they did the same. why did i have the error?
win98 said:
The Failure:UnauthorizedAccessException: Invalid cross-thread access
why did i have the error?
Click to expand...
Click to collapse
The exception you've got show exactly what's wrong: you are trying to access GUI thread variables from another (BackgroundWorker) thread.
Use Dispatcher.Invoke as I recommended to you a few posts above.
thank you sensboston. id dont understand why, because i just have one bgworker, but now it works
Code:
private void BtnStart_Click(object sender, RoutedEventArgs e)
{
if (bw.IsBusy != true)
{
LblDuration.Text = "";
BtnStart.Content = "Calculating...";
Pb1.Value = 0.0;
Pb1.Maximum = Max;
bw.RunWorkerAsync();
}
}
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
DateTime StartZeit = DateTime.Now;
Dispatcher.BeginInvoke(() =>
{
LblDuration.Text = "";
BtnStart.Content = "Calculating...";
for (int i = 0; i < Pb1.Maximum; i++)
{
if ((worker.CancellationPending == true)) //Abbruchbedingung
{
e.Cancel = true;
break;
}
else //Progressbedingung
{
Pb1.Value = Pb1.Value + 1;
//PbStep();
}
}
DateTime EndZeit = DateTime.Now;
TimeSpan GemesseneZeit = EndZeit - StartZeit;
LblDuration.Text = "Duration: " + GemesseneZeit.ToString();
BtnStart.Content = "Start";
});
}
private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.LblPercentage.Text = (e.ProgressPercentage.ToString() + "%");
}
Just my progressbar isnt running fluently. still just 0% (before calc) or 100% (after calc) and no steps between
win98 said:
Just my progressbar isnt running fluently. still just 0% (before calc) or 100% (after calc) and no steps between
Click to expand...
Click to collapse
It's simple, dear Watson: your code updating progress bar too fast, without delays needed for GUI updates
sensboston said:
It's simple, dear Watson: your code updating progress bar too fast, without delays needed for GUI updates
Click to expand...
Click to collapse
yep agree with this .. what you are actually doing in the loop is not enough for you to acutally see the progressbar update .. fast little things these phones of ours
yeah, this was the first i tryed, before posting in this forum.
delay() did not work in c#.
Application.DoEvents() should work if i can believe google, but visual studio says there is no definition for doevents().
So i used
Code:
Pb1.Value++;
System.Threading.Thread.Sleep(1);
after each progressbar.value++, but this either didnt work...
what is the secret?
win98 said:
yeah, this was the first i tryed, before posting in this forum.
delay() did not work in c#.
Application.DoEvents() should work if i can believe google, but visual studio says there is no definition for doevents().
So i used
Code:
Pb1.Value++;
System.Threading.Thread.Sleep(1);
after each progressbar.value++, but this either didnt work...
what is the secret?
Click to expand...
Click to collapse
1 millisecond will not be enough to slow it down either
Maybe try 1000 instead ..
something else i thought of too ..
you may want to think about your design
If a progress bar is going to just flash up and complete as what you are doing is too fast .. you need to think 'is a progress bar the right control to use'
if you are going to increase the amount of work your background thread is going to do then I would say keep the progress bar
If the background thread is going to be this quick always .. then maybe a label saying 'please wait' ... and then hide the label when done .. or something similar
i tried with 1000 ms but this progress bar isnt running.
@cameronm: i want to create a "benchmark app" where the cpu counts the progressbar to 1million and measures the time. the time measuring is working correctly. i just want to get a nice GUI with a running bar, like it runs when you download and install apps from the market.
i was very long googling and found commands like progressbar.PerfomStep(); like described here http://www.java2s.com/Code/CSharp/GUI-Windows-Form/ProgressBarinC.htm
this is also c#, but i cant perfom this command. did i miss some assembly, headers or so? or is it because im doint a windows phone form and that there are less command than in a normal windows application?
You want to make a Benchmark app and you actually used :System.Threading.Thread.Sleep(*int)...!
This is not Benchmarking.
Background Worker like any other ThreadTypeClass should report it's progress via the BackgroundWorker_ProgressChanged_Event(..args).
Inside the Event either u PerformStep() either you implement your own code logic.
If even after this the worker fills instanly like "cameronm" said above then consider making the backgroundworker's Job a bit heavier or leave the progressBar and even the seperated background thread Idea cause it is not Needed.
yes, i am not luck with using a sleep command
PerformStep() is not accepted by the compiler
so you mean just counting up is to "easy". what progress could be "heavier". now i understand what cameronm meant^^
in the evening i will try more difficult calculations like sqare and multiplication of integers. would that be heavy enough?
Typing from LG quantum
Try this: make your calculations in a for loop 1-100..at each loop make progressbar.value++ .
You should be calling ReportProgress and then updating the Progress Bar in the Progress Changed function.
See: http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx
@PG2G
the link you posted was exactly the source where i learned to implement the bw_worker. but with the command you told me i got an failure in the marked line (see source code comment). It says: InvalidOperationException: Operation has already been completed.
Code:
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
double a, b, c;
DateTime StartZeit = DateTime.Now;
Dispatcher.BeginInvoke(() =>
{
LblDuration.Text = "";
BtnStart.Content = "Calculating...";
for (int i = 0; i < Pb1.Maximum/100; i++)
{
if ((worker.CancellationPending == true))
{
e.Cancel = true;
break;
}
else
{
for (int m = 0; m < 10; m++)
{
a = 3547.23; //double
b = 2354.15; //double
c = (a * b) * (a * a * b);
}
Pb1.Value++;//PbStep();
worker.ReportProgress((i * 10)); //Failure here//
}
}
DateTime EndZeit = DateTime.Now;
TimeSpan GemesseneZeit = EndZeit - StartZeit;
LblDuration.Text = "Duration: " + GemesseneZeit.ToString();
BtnStart.Content = "Start";
});
}
@Freeboss
i tried it with your loop and a double calculation but it didnt work...
im going crazy, in vb i can do this in 10 minutes^^
Hello!
I have file store.vol copy from Windows phone device(HTC HD7). I use EDB API to read it.
My problem: I could not open store.vol file. ERROR_BAD_FORMAT.
How can I open this file.
Thanks!!!
My code:
Code:
#include "stdafx.h"
#include "Winphone7_Lib.h"
#include "clsReadEDB.h"
#include <iosfwd>
#define EDB
extern "C"
{
#include <windbase_edb.h>
}
// clsReadEDB
IMPLEMENT_DYNAMIC(clsReadEDB, CWnd)
clsReadEDB::clsReadEDB()
{
}
void clsReadEDB::readFile(char* path)
{
CEGUID guid;
CEVOLUMEOPTIONS cevo = {0};
cevo.wVersion = 1;
CEOIDINFOEX oidInfo = {0};
wchar_t buff[250];
HANDLE hSes, hBD, hBDS;
BOOL rez;
rez = CeMountDBVolEx(&guid, L"store.vol", &cevo,OPEN_EXISTING);
if (rez == FALSE) {
}
DWORD dw = GetLastError();
hBD = CeFindFirstDatabaseEx(&guid, 0);
if (hBD != INVALID_HANDLE_VALUE)
{
oidInfo.wVersion = CEOIDINFOEX_VERSION;
oidInfo.wObjType = OBJTYPE_DATABASE;
//creare sesiune
hSes = CeCreateSession(&guid);
if (hSes == INVALID_HANDLE_VALUE) {/* error */}
CEOID oidBD = CeFindNextDatabaseEx(hBD, &guid);
while (oidBD != 0)
{
//obtain database information
rez = CeOidGetInfoEx2(&guid, oidBD, &oidInfo);
if (rez != TRUE) {/* error */}
//open database
hBDS = CeOpenDatabaseInSession(hSes, &guid, &oidBD,
oidInfo.infDatabase.szDbaseName, NULL, CEDB_AUTOINCREMENT, NULL);
if (hBDS == INVALID_HANDLE_VALUE) {/* error */}
PCEPROPVAL pInreg = NULL;
PBYTE pBuffInreg = NULL;//memory is allocated by function
WORD wProp;//number of properties
DWORD dwLgInreg;// record lengths
//memory is allocatd by function
CEOID ceoid = CeReadRecordPropsEx(hBDS, CEDB_ALLOWREALLOC, &wProp, NULL,
&(LPBYTE)pBuffInreg, &dwLgInreg, NULL);
int k = 0;
while(ceoid != 0)
{
pInreg = (PCEPROPVAL)pBuffInreg;
//for each field
for (int i = 0; i < wProp; i++)
{
switch(LOWORD(pInreg->propid))
{
case CEVT_LPWSTR:
//process string values
break;
//integers
case CEVT_I2:
case CEVT_I4:
case CEVT_UI2:
case CEVT_UI4:
case CEVT_BLOB:
case CEVT_BOOL:
//process integer values
break;
case CEVT_R8:
//process floating point values
break;
default:
//other types
break;
}
OutputDebugString(buff);
//next field
pInreg++;
}
LocalFree(pBuffInreg);
//next record
ceoid = CeReadRecordPropsEx(hBDS, CEDB_ALLOWREALLOC, &wProp, NULL,
&(LPBYTE)pBuffInreg, &dwLgInreg, NULL);
k++;
}
CloseHandle(hBDS);
//next database
oidBD = CeFindNextDatabaseEx(hBD, &guid);
}
CloseHandle(hBD);
CloseHandle(hSes);
}
CeUnmountDBVol(&guid);
}
clsReadEDB::~clsReadEDB()
{
}