Now, we all write pages and HTML5 apps that must work in Mac/Linux/Windows/iPhone/iPad/S3/Nexus... you name it.
And sadly not all browsers behave the same, so a common problem is that you have to bind your code to all sort of events.
My friend Luis Diego send me a nice javascript library that tries to use the microsoft win8 idea of unified all these events under an umbrella of pointer events.
Pointer.js is the library proposed there. I tried it on my HTC WP7 and not everything works. On my pc works very nice and still need to tried on some mobile devices.
I might need some tune up but is a great start.
If you try to upload large files you might get an exception like
HttpException: Maximum request lenght exceeded.
This problem occurs because the default value for the maxRequestLength parameter in the section
of the machine.config or Web.config file is 4096 (4M).
So any file with a size bigger will fail.
However I think that the max size that you can write here is 2G 2097151
Some info can be found here: http://support.microsoft.com/default.aspx?scid=kb;EN-US;295626
So to change that for 512mb use something like:
<configuration>
<system.web>
<httpRuntime maxRequestLength="524288" />
</system.web>
</configuration>
It happen to me that I had a website working perfectly in my IIS and when I went to publish it it looked completely distortionated.
Why !! The eternal why.
I ended finding that it had something to do with the compatibility mode of IE, but why was it changing. It looks like it has some relation with the IIS version. Not sure why.
But the fix is to do something like:
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true" />
<httpProtocol> <customHeaders> <add name="X-UA-Compatible" value="IE=edge" /> </customHeaders> </httpProtocol>
</system.webServer>
This meta tag instructs the IE to set the compatibility mode to the highest value.
You can use other values as IE7 or IE8So just put that and your site will look nice again :)
Today someone asked what is a way to send messages between two .NET exes.
mmm Well. Interesting question. There are several approaches.
1. .NET Remoting
.NET remoting is not a new technology but is a core part of the
.NET framework and it's always available:
For an example see this code from: http://www.codeproject.com/Articles/62813/NET-Remoting-Events-Explained
2. Named Pipes
This is vb.net example: http://support.microsoft.com/kb/871044
3. WCF
WCF is a great option even if you have legacy VB6 code you can use the SOAP Client to communicate
with the service:
This link http://www.aspfree.com/c/a/VB.NET/Calling-a-Web-Service-using-VB6-with-SOAP-30/
shows an example calling a Coldfusion Service but use it as a base for calling
a WCF service
You can also integrate WCF with COM+ http://msdn.microsoft.com/en-us/library/bb735856.aspx
4. Windows Messages
There is a nice project that wrap it all up for you so you can use this solution:
http://www.codeproject.com/Articles/17606/NET-Interprocess-Communication
If you were looking for HTML5 and CSS3 support, web standards update is a great choice.
However this install tool does not work if you installation is not in the defualt Visual Studio directory:
C:\Program Files\Microsoft Visual Studio 10.0\Common7
One way to fix it is to run the Web Standard update and after the update look for the default dir:
C:\Program Files\Microsoft Visual Studio 10.0\Common7
and copy and merge its contents in your current instalation directory
Is very simple. To get the control with the focus do something just use the FocusManager.GetFocusedElement()
See: http://msdn.microsoft.com/en-us/library/system.windows.input.focusmanager(v=VS.95).aspx
You can also add an extension method like:
public static class FocusExtensionMethods
{
public static bool HasFocus(this Control c)
{
return FocusManager.GetFocusedElement() == c;
}
}
My friend Jesus has been working on an interesting task. We has been implementing some code so we can connect
a WIA compatible scanner with a Silverlight App.
Once he got the scanner to work, he had to send that data to the Silverlight app.
Something like:
var stream = new MemoryStream(data);
BitmapImage bmp = new BitmapImage();
bmp.SetSource(stream);
During this interesting test the infamous Catastrophic failure was raised. This exception
is caused if the data is in an invalid or unsupported format. You can see about this issue in
these links:
http://connect.microsoft.com/VisualStudio/feedback/details/436047/silverlight-3-bitmapimage-setsource-catastrophic-failure
http://forums.silverlight.net/p/232426/569554.aspx
However, Jesus found a interesting solution. Use an appropriate encoder. He found this page:
http://blogs.msdn.com/b/jstegman/archive/2009/09/08/silverlight-3-sample-updates.aspx
With references of Encoder for: .ICO, BMP and GIF
With this code you can do something beautiful like this:
Stream file = …
// Decode
Texture texture = Silverlight.Samples.BMPDecoder.Decode(file);
//Texture is another class in this sample that will return a writeable Bitmap
//And with that texture object you just load the image like this:
WriteableBitmap wb = texture.GetWriteableBitmap();
wb.Invalidate();
img.Source = wb;
Nice!!!!
Azure Storage easily gives you 10TB of storage.
So a common question, is how can you upload information to your Storage Account.
FTP is a standard way of uploading files but is usually not available in Azure.
However is it possible to implement something that mimics an FTP but allows you to save data to the
FTP server?
Well I thought on trying on implementing something like that but luckily several guys have already
done that.
Richard Parker has a post on his blog and has also posted the source code in
codeplex FTP2Azure. This implementation works with clients like FileZile. It only does
Active connections.
Maarten Balliauw also did some similar work. He did not provided the source code but
he does active and passive connections so a mix with Richard’s post can be interesting.
What is the ROT?
“Using ROT (Running Object Table) is a great way to establish interprocess communication between two windows applications. From a purely logical aspect, one application registers a pointer to an instance of a class in the ROT, the other one gets a pointer pointing to the same instance of the registered class and therefore can use the same instance of the class via this pointer. The class that is registered has to be a COM class, otherwise it can be written in any language. The application that will retrieve the pointer from the ROT can be written in any language that can use COM, as ROT gives a pointer to a COM interface.”
Can it be implemented in .NET?
Sure a .NET application can be exposed thru COM and then its pointer can be gotten and consumed by other applications querying the ROT.
And excelent example can be found here: http://www.codeproject.com/KB/COM/ROTStuff.aspx
As always it has its caveats. Be careful.
Obvious replacement?
Well if what you want is (Interprocess Communication) IPC,there are several options in .NET :
* Classical .NET remoting which is very simple and stable to
* Named Pipes see an example here http://bartdesmet.net/blogs/bart/archive/2007/04/12/getting-started-with-named-pipes.aspx
* or WCF with Named Pipes, an example here http://www.codeproject.com/KB/WCF/WCF_CommOptions_part1.aspx
WCF can be an interesting option specially if we were doing things like DCOM and Remote monikers.
In Silverlight you can put an application in FullScreen mode using code like the one exposed here:
http://msdn.microsoft.com/en-us/library/cc189023(v=vs.95).aspx
However that does not allows you to start the application in FullScreen, because the application
can only enter in FullScreen with an user event.
So, one possible approach is to use javascript. So you can do something like this:
<HTML>
<HEAD>
<script LANGUAGE="JavaScript">
<!--
closeTime = "2000";
function closeTimer() {
setTimeout("newURL()", closeTime);
}
function newURL() {
newURLWindow = window.open("FullScreenModeTestPage.html", "redirect", "fullscreen=yes");
self.close()
}
//-->
</script>
<BODY onLoad="closeTimer()">
<center>
<H1>YOU WILL BE REDIRECTED; NEW A NEW WINDOW WILL OPEN IN FULLSCREEN; PRESS ALT+F4 TO CLOSE IT!</H1>
</center>
</BODY>
</HTML>
I’m very fond of one of our newest products www.silverlightmigration.com
It provides a way to refresh your applications to take full advantage of XAML,
solves deployment issues, runs in Windows, Mac OSX and in some Linux with
MoonLight
And we are event tuning it up for the next jump: Windows 8… keep tuned for that.
One of the things a like most about this solution is XAML theming.
In general there are good themes but today I would like to recommend the SystemColors theme
from http://blogs.msdn.com/b/corrinab/archive/2010/04/12/9994045.aspx
You can download it from here.
This theme allows you to style all core, sdk and toolkit controls so they will use the theme that
you currently have in Windows. These might be very useful for some LOB applications,
so the applications can see more like native applications, and with the advent of Silverlight 5 and more
native integration, better Out-of-Browser execution I think it is just fine.
See some screen shots:
Out of the blue, I just started getting this obnoxious exception. Why?? Why meeeeeee!!
Another weird thing is that is was only from my test server. Again Why?>>> Why Meeee!!!
In general when I executed some stored procedures or performed select staments againts the
Oracle database I just got that exception.
ORA-01843: not a valid month
CAUSE:
The source of the problem is that when a table has a date stored in a format that the client is not able
to understand due to format differentes it will throw this message.
For example, if the table is storing dates like ‘DD-MM-YY’, (that is day-month-year european format)
and the client tries to read the date as ‘MM-DD-YY’ or viceversa. In this case we can see that the
month number is confused with the day and it is very likely that there will be dates with a month value
bigger that 12.
SOLUTION:
The solution to this problem is to tell the client the right format to use for dates. This is part of the session values
in oralce. Part of those values can be queries with the following statement:
select * from nls_session_parameters
In the query results, we can see the value of the NLS_DATE_FORMAT that is being used by the client.
You can take several actions.
1. If you are just performing a query on SQL PLUS and is just an isolated query you can just change that value for
your current session by executing:
alter session set NLS_DATE_FORMAT=’DD-MM-RR’
This will take effect ONLY for the actual session. In this example we can see that the format is being changed to
‘day-month-year’. The RR, indicates the year.
2. If you want a more permanent change or at least something that applies to all your session. You can:
2.1. Create an After Logon Trigger something like:
CREATE OR REPLACE TRIGGER LOGINTRG AFTER LOGON ON DATABASE
BEGIN EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_DATE_FORMAT=''DD-MM-RR'''; END LOGINTRG;
2.2. Option 2. Go to the Registry and locate
\\HKEY_LOCAL_ MACHINE\SOFTWARE\ORACLE\KEY_HOMENAME\
For example in my case it was
\\HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\HOME0
And create an String Key called NLS_DATE_FORMAT and set it to DD-MM-RR
Today I had an stored procedure defined in a package and I didn’t know how to call it.
And my stored procedure returned a cursor and I needed to see the results.
So after some tests this is the way to perform this. You can use code like the following:
variable r refcursor -- use this if you have an out parameter that is an out cursor
DECLARE
-- Declare a variable for each of your stored procedure arguments
VAR_IN_1 VARCHAR2(32767);
VAR_IN_2 VARCHAR2(32767);
VAR_IN_3 VARCHAR2(32767);
INFO sys_refcursor;
BEGIN
-- Init the variables with the parameter you want to use to test the stored procedure
VAR_IN_1 := 'Param1';
VAR_IN_2 := 'Param2';
VAR_IN_3 := 'Param3';
-- Call the stored procedure. You should write something like schema.package.storedprocedure( param1, param2, ..., paramN);
MYSCHEMA.PKG_TEST.TEST_STORED_PROC ( VAR_IN_1, VAR_IN_2, VAR_IN_3, INFO );
-- If one of the parameters was an out cursor assign it to the r variable to be able to see the results
:r := PC_INFO;
COMMIT;
END;
-- Execute this code in SQL PLUS
And after executing it just call in the SQL PLUS prompt
PRINT r to see cursor results
I just came back from executing a Ready assessment for a company in Minnesota, where I analyzed 740,000 lines of code in a VB6 application, of which 660,000 belonged to a single Visual Basic project (.vbp). This is actually the largest single .vbp I have seen so far, beating the previous record of about 500,000 lines of code held by an European company. We have migrated plenty of applications that contain 1+ million lines of code, but they are usually distributed across many .vbp’s.
Though unusual, single vbp’s of this size are perfectly manageable from a migration standpoint, and here are some things that can be done to deal with them:
- Ensure that the migration computer has at the very minimum, 3GB of RAM.
- Look for customization opportunities before you start migrating the code. Customizing the VBUC for this specific VBP can reduce manual effort drastically.
- When making manual changes, start with a small team until you get the project to compile, especially if migrating to VB.NET as the compiler has a maximum of build errors that it can show at any given time.
- Once the application compiles, increase the team size and go for Visual Equivalence by distributing the different forms and user controls across your developers.
Crystal Reports was one of the most popular reporting engines in VB6, and still holds a strong market presence with its .NET version. However, the object model in the .NET version of Crystal has changed so dramatically from the VB6 days that automating this conversion is not be cost-effective in most cases. These are the options when dealing with Crystal Reports in an application to be migrated to .NET:
- Use COM Interop: we have successfully migrated many applications with Crystal Reports through COM Interop. However, this only works when the report objects are populated using Crystal’s own querying engine (for example, sending a SQL string to Crystal so it can retrieve the data directly from the database), instead of providing an already-populated RecordSet as a data source for the report. This is because once the application is ported to .NET, its RecordSets will become ADO.NET DataSets (or Helper Classes inheriting from DataSet), which will not be compatible with the legacy version of Crystal. This can be fixed this by disabling the conversion of ADO to ADO.NET, but this is not desirable in most enterprise applications, and may compromise future maintainability and enhancements.
- Replace with Crystal .NET or another .NET-compatible reporting engine: this is also a popular option among our clients, as it removes the legacy Crystal component. On the other hand, this replacement is manual and will require adjustments to the report layout, if converting to the .NET version of Crystal, or even a rewrite of the reports if migrating to other engines.
Visual Basic 6.0 property pages allow you to work around the
limitations of the Visual Basic Property Browser. For example,
you can use property pages to give users a way to add a collections of
colors to a color list user control.
In the property page you would write code that manages the collection,
something beyond the capabilities of the Visual Basic Property Browser.
In contrast, the Visual Basic .NET Property Browser can be used
to edit any .NET variable type or class. Property Pages are no longer needed.
The Upgrade Wizard and the VBUC do not automatically upgrade your
Visual Basic 6.0 property pages but they can sure be of help.
What if you really what to keep those property pages? Is there any workaround.
mmmm Sure there is.
You can follow these steps.
1. Before migrating your Visual Basic 6.0 project with the VBUC
modify your property pages (.pag) files to resemble common Visual Basic 6.0 forms.
For example a property page looks like this:
VERSION 5.00
Begin VB.PropertyPage PropertyPage1
Caption = "PropertyPage1"
ClientHeight = 3600
ClientLeft = 0
ClientTop = 0
ClientWidth = 4800
PaletteMode = 0 'Halftone
ScaleHeight = 3600
ScaleWidth = 4800
Begin VB.TextBox Text1
Height = 495
Left = 480
TabIndex = 1
Text = "Text1"
Top = 1200
Width = 2175
End
Begin VB.CommandButton Command1
Caption = "Command1"
Height = 615
Left = 3120
TabIndex = 0
Top = 480
Width = 1455
End
Begin VB.Label Label1
Caption = "Label1"
Height = 375
Left = 240
TabIndex = 2
Top = 600
Width = 1815
End
End
Attribute VB_Name = "PropertyPage1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Can be turned into a Form, to ease migration with simple changes:
VERSION 5.00
Begin VB.Form PropertyPage1
Caption = "PropertyPage1"
ClientHeight = 3600
ClientLeft = 0
ClientTop = 0
ClientWidth = 4800
PaletteMode = 0 'Halftone
ScaleHeight = 3600
ScaleWidth = 4800
Begin VB.TextBox Text1
Height = 495
Left = 480
TabIndex = 1
Text = "Text1"
Top = 1200
Width = 2175
End
Begin VB.CommandButton Command1
Caption = "Command1"
Height = 615
Left = 3120
TabIndex = 0
Top = 480
Width = 1455
End
Begin VB.Label Label1
Caption = "Label1"
Height = 375
Left = 240
TabIndex = 2
Top = 600
Width = 1815
End
End
Attribute VB_Name = "PropertyPage1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
If the form had a event like:
Private Sub PropertyPage_Initialize()
End Sub
Change that to Form_Load()
2. Rename the file from .pag to .frm.
3. Remove the .pag from the VB6 project
4. Add the .frm file to the VB6 project
5. Run the VBUC tool.
Once migrated you have a close migration of your original Property Page.
Remember however that some things change in .NET and you will need to manually finish some details.
For example, you need to review code in the
PropertyPage_ApplyChanges(),
PropertyPage_EditProperty(PropertyName As String)
PropertyPage_SelectionChanged().
Ok. Once you take your Property Page to .NET how do you integrate it with your control.
Well that’s easy. There you could create a ControlDesigner or just use an UITypeEditor.
Let’s see the UITypeEditor aproach.
The general idea with this aproach is to provide an UITypeEditor (this is just a way to provide an
editor in the property Browser that is not supported by default. And taking advantage of that editor
we will show the form that was produced after migrating out Property Pages. If you want an interface
more similar to what you had on Visual Basic 6.0 you can modify the property page and add a TabControl.
Ok. So these are the steps to follow:
1. First you need to create a type for which you will provide a Type Editor. We will call this type CustomData
namespace CustomEditor
{
public class CustomData
{
}
}
2.Now we will add a property to our control.
public CustomData Custom
{
get;
set;
}
3. Now add attributes to associate an editor
[Description("Custom"), Editor(typeof(CustomDataEditor), typeof(UITypeEditor))]
public CustomData Custom
{
get;
set;
}
4. And now lets implement the CustomDataEditor
using System.Windows.Forms.Design;
namespace CustomEditor
{
public class CustomDataEditor : UITypeEditor
{
public CustomDataEditor() {}
public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value)
{
IWindowsFormsEditorService frmsvr = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
if (frmsvr == null) return null;
PropertyPageForm propPage = new PropertyPageForm();
propPage.control = (MyControl)context.Instance;
frmsvr.ShowDialog(f);
return null;
}
}
}
5. In the previous put attention to the highlighted details. What we are doing is getting a reference
to the WindowsFormEditor service so we property open the PropertyPage that has now been turned into a form.
It is important that you add a public property to the migrated PropertyPage like:
public MyControl control { get; set; };
because that will give you a reference to the actual control that is on the form. The property page is just an interface
you will need to set the values into properties on your control, in order for them to be serialized.
6. Once you do that, when you see the property editor for your control you will see something like:
When you press the … button it will show up your property page form.
You could also add other visual elements like:
Or
But that is maybe for another post.
Regards
Fixing memory leaks is sometimes hard. Because even if you track which is the instance
that is being retained, is difficult to determine WHERE was it created.
Another problem I have found difficult to tackle is when you get an exception because of
code that was put in a finalizer (yes I know that putting code in a Finalizer doesn’t sound like the
best programming practice but sometime I just have to give maintenance to code that does that).
So, my friend Jose de Jesus showed me a nice tip to identify where are those objects being created.
He told me to do the following:
1. Add an instance variable like:
public System.Diagnostics.StackTrace myClassStackTrace = new System.Diagnostics.StackTrace();
2. Just by doing that I can inspect that field and identify where was this particular instance created!.
Cheers
Some time ago, I helped a British company to
prepare and plan for their in-house migration project. One of the first things that we checked were
the project effort estimates, so we could build a work breakdown structure
based on the estimated effort for each activity; both the company’s developers
and ArtinSoft’s had made separate estimates for the project so we could compare
and discuss them.
To my surprise, the company’s estimates were
significantly lower than ours, so we started digging into the details to find
where the biggest discrepancies were, and realized that their estimate
consisted of developer effort only, with no testing or administrative work. They were so focused on manual changes,
Upgrade Warnings and compile errors that they omitted the QA process necessary
to validate that the application is stable and working as the original
one.
As with other development projects, migrations
do require a full testing of the converted application before it is released to
production. You may find less bugs than
you would if you were coding from scratch, but the complete QA cycle is vital
in order to ensure stability and Functional Equivalence. Also, don’t forget to include effort for
administrative tasks as well as other activities that you may have in your
projects, depending on your project management methodology.
Here is a list of some things that you should consider for Internationalization of Applications.
1. CurrentUICulture and CurrentCulture.
Is is better if you don’t change CurrentUICulture form the the Operating System
2. Windows Forms Layout
Forms must be set Localizable property to true.
This will allow you to define different layouts for your forms depending on the current culture.
3. Strongly Typed Resources.
Instead of something like MessageBox.Show(“Invalid code”) use something like:
MessageBox.Show(resourceManager.GetString(“InvalidCode”)) or even better if you strongly type it:
MessageBox.Show(Form1Resources.InvalidCode);
4. Localize Exceptions messages.
If you include messages in your exceptions that will be shown somehow
on the user interface it is better if your localize those strings also.
If exceptions messages are only for developers then you might not need this.
5.Relate Internationalization sensitive values to the Culture Info
For example
a) Extension methods something like:
CurrentCulture.GetPostalCode();
static class CultureInforExtensions
{
public static string GetPostalCode(this CultureInfo cultureInfo)
{
return new PostalCode(cultureInfo.Name).ToString();
}
}
and then use it like:
maskedTextBox1.Mask = CultureInfo.CurrentCulture.GetPostalCode()
b) Customized CultureInfo it can be helpful for
- Change inappropiate Culture Information
- Supplementary Cultures
- New Combinations of Existing Languages and Regios (for example: Spanish (United States))
6. Right To Left
In some languages Right to Left is important and is an important aspect to consider.
In your forms you have to set the RightToLeftLayout to true and RightToLeft to Yes.
However some controls do not have rtl layoout when RightToLeft=yes: Panel, GroupBos, TabPages and SplitContainerPanels.
You need to rearrange the items in these controls to flow from RightToLeft manually.
This is an example of rearranging the layout of the controls programmatically at runtime, without changing the Form at design-time:
int NumberOfControls = ParentPanel.Controls.Count;
for ( int i=0; i<NumberOfControls;i++)
{
ParentPanel.Controls[i].Left = ParentPanel.Width -
(ParentPanel.Controls[i].Left + ParentPanel.Controls[i].Width);
}
This code iterates into all the controls in the ParentPanel and changes their location to be rtl oriented.
Other problematic controls are: MainMenu, ToolBar, StatusBar MenuStrip, ToolStrip, StatusStrip and ContextMenuString
Other advises:
When you develop multi-lingual application you are bound to change your Forms direction to rtl programmatically at runtime.
There are several techniques to detect the OS language and display your application with the appropriate language and rtl settings, here are some ideas:
The old technique, you would need to detect your UIculture and change the RightToLeft value accordingly.
public static bool CultureInfoIsRightToLeft()
{
string cultureInfoLanguage = System.Globalization.CultureInfo.CurrentUICulture.TwoLetterISOLanguageName;
return
cultureInfoLanguage == "ar" ||
cultureInfoLanguage == "div" ||
cultureInfoLanguage == "fa" ||
cultureInfoLanguage == "syr" ||
cultureInfoLanguage == " ur " ;
}
In Visual Studio 2005, you have a new property TextInfo.IsRightToLeft that indicates the direction of each culture. This is a simple code snippet to detect the culture direction.
private static bool CultureInfoIsRightToLeft()
{
return System.Globalization.CultureInfo.CurrentUICulture.TextInfo.IsRightToLeft;
}
GDI+
In case you implement your own drawing, you need to specify how your digits would appear in your DrawString. This is achieved using the StringFormat.SetDigitSubstitution. For more info to this method please refer to the documentation . Below is a code snippet that shows how to display digits using the different enums.
private void IndicDigits_Paint( object sender, PaintEventArgs e)
{
StringFormat StrFormat = new StringFormat ();
int AraLCID = new System.Globalization. CultureInfo ( "ar-eg" ).LCID;
StrFormat.SetDigitSubstitution(AraLCID, StringDigitSubstitute .National);
e.Graphics.DrawString( "Digit Substitution National 0,1,2,3,4,5,6,7,8,9" , this .Font, newSolidBrush ( this .ForeColor), new PointF (10, 10), StrFormat);
StrFormat.SetDigitSubstitution(AraLCID, StringDigitSubstitute .Traditional);
e.Graphics.DrawString( "Digit Substitution Traditional 0,1,2,3,4,5,6,7,8,9" , this .Font, newSolidBrush ( this .ForeColor), new PointF (10, 30), StrFormat);
StrFormat.SetDigitSubstitution(AraLCID, StringDigitSubstitute .None);
e.Graphics.DrawString( "Digit Substitution None 0,1,2,3,4,5,6,7,8,9" , this .Font, newSolidBrush ( this .ForeColor), new PointF (10, 50), StrFormat);
StrFormat.SetDigitSubstitution(AraLCID, StringDigitSubstitute .User);
e.Graphics.DrawString( "Digit Substitution User 0,1,2,3,4,5,6,7,8,9" , this .Font, newSolidBrush ( this .ForeColor), new PointF (10, 70), StrFormat);
}
A friend at work asked me how do I make my form bigger that the screen resolution. I was not able to do it, but
he google it and found a solution from: http://social.msdn.microsoft.com/Forums/en/vblanguage/thread/65c48eea-408a-45ed-a1cc-ea0336047798
This is just the transliteration of that code in C# just as a reference
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class Form1 : Form
{
[DllImport("User32.dll", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
private static extern bool MoveWindow(IntPtr hWnd, int x, int y, int w, int h, bool Repaint);
private void Form1_Load(System.Object sender, System.EventArgs e)
{
this.MaximumSize = new Size(5000, 800);
bool Result = MoveWindow(this.Handle, this.Left, this.Top, 5000, 500, true);
}
public Form1()
{
Load += Form1_Load;
}
}