.net.devcity.weekly ---
If you are unable to see the message, visit http://www.devcity.net/newsletter/archive/devcity/devcity20051120.htm

Advertisement

AdvertisementAdvertisement

The newsletter is compiled by DevCity.NET NewsMasters Ged Mead and Mike McIntyre

After a short break DevCity.NET newsletter is back.

We launched new web site that aggregates content from variuos Visual Basic related resources - http://vbfeeds.com - read on for more details.

Advertisement

Table Of Content:

Advertisement
Diary of a .NET Newbie: A Bit of a Drag

by Ged Mead

Sometimes little things can be quite impressive.
At least, my wife always tells me that. But maybe we'd better not go down that road just now.

Dragging and dropping text between controls is a little thing. It's made very easy in VB.NET, although I can't help thinking sometimes that the syntax makes it all sound more difficult than it really is.

Take the situation where you want to drag items from a listbox and display them in textboxes. The basic requirements for this would be:
1. Ensure that the receiving textboxes have their AllowDrop Property set to True. This can be done via the Properties Window or in code.

2. Identify which item in the listbox the user wants to drag.
The SelectedItem Property would seem to do the trick :

'  Declare an integer variable to hold the chosen item's index number
Dim idx As Integer

'  Make a note of it when user selects
Private Sub ListBox1_MouseDown(ByVal sender As Object, _
  ByVal e As System.Windows.Forms.MouseEventArgs) _
  Handles ListBox1.MouseDown

    idx = ListBox1.SelectedIndex

End Sub

3. If the user is serious about dragging and dropping this listbox item, the mouse button will be held down while the mouse moves inside the listbox client area. Here's a neat way of testing for that case:

Private Sub ListBox1_MouseMove(ByVal sender As Object, _
  ByVal e As System.Windows.Forms.MouseEventArgs) _
  Handles ListBox1.MouseMove

    If ((e.Button And MouseButtons.Left) = MouseButtons.Left) Then
        ListBox1.DoDragDrop(ListBox1.Items(idx), DragDropEffects.Move)
    End If

End Sub

4. When the user drags the text from the listbox into the receiving textbox, the textbox's DragEnter event fires. This is very useful as we can check that an appropriate data type is being dragged into the box's client area. In this example, we need it to be text (Duh):

Private Sub TextBoxes_DragEnter(ByVal sender As Object, _
  ByVal e As System.Windows.Forms.DragEventArgs) _
  Handles TextBox1.DragEnter, TextBox2.DragEnter, TextBox3.DragEnter

    If e.Data.GetDataPresent(DataFormats.Text) = True Then
        e.Effect = DragDropEffects.Move  ' Give OK feedback
    End If

End Sub

It's not immediately obvious from the code above, but if the data being dragged into the text box isn't text then the "No entry" type icon will continue to be shown to the user as the cursor moves into the textbox.

Even more usefully, the value of e.Effect will not be DragDropEffects.Move. So,

5. In the final procedure, we can test for e.Effect and only drop the text into the textbox if e.Effect is indeed DragDropEffects.Move

Private Sub TextBoxes_DragDrop(ByVal sender As Object, _
  ByVal e As System.Windows.Forms.DragEventArgs) _
  Handles TextBox1.DragDrop, TextBox2.DragDrop, TextBox3.DragDrop

    Dim tb As TextBox = CType(sender, TextBox)
    '  If we are moving text ....
    If e.Effect = DragDropEffects.Move Then
        '  First let's see if there is any text here already...
        If tb.Text <> "" Then
            '  If there is, add it back to the listbox
            ListBox1.Items.Add(tb.Text)
        End If
        '  Now drop the text into this textbox
        tb.Text = CType(e.Data.GetData(DataFormats.Text), String)
        '  Finally, remove the moved line from the listbox
        ListBox1.Items.RemoveAt(idx)
    End If

End Sub

You'll see from the comments that this procedure also moves any text from the receiving textbox and adds it to the listbox. It wraps up the proceedings by removing the moved listbox item from the list.

I've seen lots of questions in the past where folks have wanted to know how to move selected list items from the listbox to a textbox when an item is clicked. As far as I can remember, I think this is the first time I've seen the problem approached from a drag and drop perspective.

One of the plus points of doing it this way is that it requires the user to physically drag the item around. There's no scope for misunderstanding. Whereas with the "user clicks an item and it moves" approach, there is always the possibility that an unwary user just happens to click on a listbox item and - whoops! - it's whipped out into a textbox and, usually, the user has no way of reinstating it back into the list.

I plan to do some experimenting with Drag and Drop when I get some spare time, so we'll maybe be seeing this subject again in the Diary. Dragging text and/or images into controls which can accept either, for example, might be interesting territory to explore.

Thanks to VBCity member Galley for posing the question in the first place and to garylemmon for providing the code logic for the ListBox MouseMove event. Also for the pointer to the ListBox's IndexFromPoint method. Although I didn't use it in this example, it's definitely handy to know about it and was a new method to me. It just goes to prove what I've believed for a long time: the more you know, the more you know you don't know.

- Junior (Ged Mead aka XTab, xtab@vbcity.com)

by Mike McIntyre

Part 2 of 3

This second installment of the article discusses the 'Cookieless' session state management option and presents a table that compares using cookies to using a 'Cookieless' session.

Cookieless Session

A Cookieless Session is an alternative mechanism for associating a client's session state on the host across requests made by the client, without using cookies.

A 'mangled URL' containing an encrypted session ID, instead of a session ID cookie, is used to associate a client's state on the host across requests made by the client.

Cookieless sessions embed the session ID in the URL to provide a way for the Web site to correctly identify the user making the request

When the server receives a request, it extracts the encoded session key from the request URL and links the request to the client's Session object

On subsequent navigation, either via anchor tags or explicit programmatic redirections, ASP.NET will alter the target URL to embed the session key as well. NOTE: This implicit URL mangling works only for relative URLs.

Client's who have disabled cookies in their browser CAN use an ASP.NET application that uses a cookieless session.

Configuring a Web Application to Use a Cookieless Session

Default settings for ASP.NET session state are defined in the machine.config file and can be overridden in the web.config file in the application's root folder. To enable cookieless sessions in an application, change the following web.config configuration setting.

<configuration >
  <system.web>
    <sessionState cookieless="true" />
  </system.web >
</configuration >

How Cookieless Sessions Work

The implementation of cookieless sessions results from collaboration between two runtime modules-the standard Session HTTP module named SessionStateModule and an executable known as aspnet_filter.dll.

When a request for a new browser session comes in, the session state module reads the <sessionState> configuration settings in the web.config file. If the cookieless attribute of the <sessionState> section is set to true, the module generates a new session ID, mangles the response URL by inserting the session ID just before the resource name, and then redirects the browser to the new URL using the HTTP 302 command.

When each request arrives at the IIS gate the aspnet_filter.dll examines the request. If the URL embeds a session ID in parentheses, then the session ID is extracted and copied into a request header named AspFilterSessionId. The URL is then rewritten to look like the originally requested resource and let go. The ASP.NET session state module retrieves the session ID from the request header and proceeds with session-state binding.

ASP.NET Forms Authentication and Cookies

One of ASP.Net's authentication mechanisms, Forms authentication, uses cookies.

If the application authenticates the client, it issues a cookie to the client that the client presents on subsequent requests. If a request for a protected resource does not contain the cookie, the application redirects the client to the logon page.

An ASP.NET application that uses Forms authentication must use cookies.

Cookieless Session can not be used in an application that uses ASP.NET Forms authentication.

Comparison of Cookies to Cookieless Session

CookiesCookieless
Support clients who have disabled cookies.NO YES
Supports all browsers.NOYES
Support state cookies.YESNO
Support web browser book marking (Favorites).YESNO
Supports manually typed URLs.YESNO
Support mobile devices.YESVery few mobile devices
support cookieless sessions.
Protect sensitive data.Requires more code and code review than using a cookieless session.YES - by eliminating cookies and the intrinsic
risks associated with them.
Support absolute fully qualified URLs.YESYES - but requires special coding practices.
Cookieless sessions require that you always use relative URLs, like in ASP.NET post backs.
To use absolute URLs, use the ApplyAppPathModifier method on the HttpResponse class:
ApplyAppPathModifier("/test/page.aspx")
Support ASP.NET Forms authentication.YESNO. (Yes in .NET 2005)
Subject to cookie replay attacks.YESNO
Subject to session replay attacks.YESYES
Subject to injurious manipulation by a hackerYESYES, but to a much lesser extent than cookies
Subject to parameter manipulation.YESNO

Next Installment: Security Considerations for Cookies and Cookieless Session

by Fadzai Chamba

Editor's Note: The original article ("Task MisManager - Disabling Ctrl+Alt+Del in Windows XP/2K using VB.NET") was published in the Jul 15th newsletter. Fadzai has posted a follow up in the Thread where the code from his original Task MisManager article was placed. The additional information is reproduced below:

One thing that I did do just before the article was published was decide that if the registry key is hidden in the first place, somebody at Microsoft had a pretty good reason for that to be so so I modified the code but could not get it to Ged in time for the aricle to be posted. What is needed in this case is to modify the SetTaskManager method to what I have provided and now when Task manager is enabled, the associated registry key is deleted so that a registry search cannot bring it up.

''' Disables or enables the task manager

Public Sub SetTaskManager(ByVal _state As TaskManagerState)
    'constant for the name of the Task manager value...
    Const _disableTASKMAN As String = "DisableTaskMgr"

    Dim reg As RegistryKey = _hkcu.OpenSubKey(_subKey, True)
    'if we got nothing, and we are supposed to be disabling it, 
    'create the key
    If reg Is Nothing AndAlso _state = TaskManagerState.Disabled Then
        reg = _hkcu.CreateSubKey(_subKey)
    ElseIf reg Is Nothing Then
        'only come here if we are enabling. we don't need to create the key
        Exit Sub
    ElseIf Not reg Is Nothing AndAlso _state = TaskManagerState.Enabled Then
        'come here if we have the key and we are enabling. 
        'There must be a reason as to why
        'Windows deletes the key so we must do the same...
        If reg.ValueCount <= 1 Then
            'delete the entire key if we have nothing or one item 
            'in there...
            _hkcu.DeleteSubKey(_subKey)
        Else
            'we have more than one, so delete the value we are 
            'interested in only...
            reg.DeleteValue(_disableTASKMAN)
        End If
        'regardless of what we found up there, bail out to 
        'avoid reseting the value...
        Exit Sub
    End If

    'change the value...
    reg.SetValue(_disableTASKMAN, CInt(_state))
 End Sub

You can read the original article by following this link to the Newsletter Archive.

.NET Upgraders: ComboBox Woes

by Neil Knobbe

Recently, I have started to convert one of my Visual Basic 6 projects over to .NET.

In the project the user at times must select names in four ComboBoxes. The possibility exists that the same list of names could appear in more than one ComboBox. As I didn't want the user to be able to select the same name more than once, one of the features of the project was the ability to determine if the User had already selected the name. If they did select a name a second time, a MessageBox would tell them that there was a duplicate name, set the Text of the ComboBox to "Select Again" and then Set Focus back to the ComboBox.

In VB6 I was able to accomplish this in the Click Event of the ComboBox. In VB.NET, however, the Click Event of a ComboBox is slightly different. With VB6, the Click Event is raised when the User selects an Item from the ComboBox, but in VB.NET the Click Event is raised when the user clicks the ComboBox Control to display the list of Items. With this subtle change of what causes the Event to be raised, I was no longer able to use the Click Event for my code. I had to use the SelectedIndexChanged Event of the ComboBox which is much like the Click Event of a VB6 ComboBox. No worries.

I placed the code needed to check the previous ComboBoxes and tested the project. I selected the same name in the second ComboBox as was in the first. I got the MessageBox telling me there was a problem and the ComboBox got Focus, but wait, there was a problem. The Text of the ComboBox was not "Select Again" as it should be; it was still the name that I had selected.

I checked my code and sure enough I hadn't forgotten to change the Text Property of the ComboBox. There it was in black and white;

ComboBox.Text = "Select Again"

I ran the project again on the off chance I had seen things wrong, but once again the Text of the ComboBox didn't change from the name I had selected from the list of Items. I spent some time trying to figure out how to set the Text of the ComboBox in the SelectedIndexChanged Event. I finally admitted defeat, and asked around for help. Several VBCity Leaders and Microsoft MVPs later I was relieved to know that the problem didn't lie with me, but rather with the VB.NET ComboBox Control. Apparently you can not set the Text of a ComboBox, using VB.NET, in the SelectedIndexChanged Event of the ComboBox. (On a side note and just to make it that much more frustrating, you can change the Text Property of the other ComboBoxes using the SelectedIndexChanged Event, just not the ComboBox that the Event Handles).

So, now I had this feature that I wanted in my project, but how was I going to implement it? I first thought of using the Validated or Validating Events of the ComboBox, but for these Events to fire the ComboBox needed to lose Focus, and I didn't want the User to be able to proceed as long as there was a duplicate name. After trying the code in several Events, I found one that seemed to suit my needs; the MouseMove Event. But there was a problem with this as well. For the MouseMove Event to be raised the User would have to move the Mouse over the ComboBox and that would not be something that they would do after selecting a name from the list. So while I seemed to be a step closer I was still not able to do what I wanted.

Then it hit me: what if I moved the mouse over the ComboBox after the User had selected a name? Could this be done? After a few experiments, I enlisted the aid of XTab (VBCity Leader, Microsoft MVP and all around nice guy). He showed me how to set the X and Y co-ordinates of the Mouse. I now use that code in the SelectedIndexChanged Event of the ComboBox. (Yes, we have come full circle now. I am back to using the SelectedIndexChanged Event as I originally thought to use, but only now for a different reason.)

I declared the Variable in a Module because I needed it to be available Globally:

Public ptCurrent As Point = Cursor.Position

Then the SelectedIndexChanged Event looked like this:

ptCurrent.X = Me.Left + CInt(ComboBox1.Left + (ComboBox1.Width * 0.99))
ptCurrent.Y = Me.Top + (ComboBox1.Top + 75)

Cursor.Position = ptCurrent

I had to fiddle a little bit to get the X and Y positions over the arrow of the ComboBox, but the Cursor moves over the ComboBox and the MouseMove Event is raised.
The MouseMove Event calls the Sub and passes the Parameters for the Sub:

CheckNamesForDoubles(TabControl1.TabPages(0), ComboBox1, Panel2)   

The Sub looks like this:

Public Sub CheckNamesForDoubles(ByVal cc As Control, ByVal Scc As Control, _
  ByVal Ecc As Control)

    ' This Sub compares the Text of the ComboBox to the previous 
    ' Name ComboBoxes.
    ' cc = Tab Page that the Controls Reside on
    ' Scc = Name ComboBox who's MouseMove Event Calls the Sub to 
    ' check for double names
    ' Ecc = Next Control to be Enabled so the User can continue if the 
    ' selected name does not match any of the other names already selected

    Dim ctl As Control  ' Declare a Variable for each of the Controls

    If Scc.Text = "" Or Scc.Text = "Select Again" Or _
      Scc.Text = "Select a Student" Then

        ' If ComboBox.Text has any of the 3 Values then Exit the Sub.
        Exit Sub

    Else
        ' The ComboBox does not have one of the 3 Values so we want 
        ' to check to see if the selected Name has already been selected.

        For Each ctl In cc.Controls
            ' Loop through all the controls on the Tab or Form 
            ' depending on which Control cc is referring to.

            If TypeOf ctl Is ComboBox Then
                ' Check to see if the Control is a ComboBox.
                If Not ctl Is Scc Then
                    ' If the Control is a ComboBox and it is not 
                    ' the ComboBox that is callng the Sub. 
                    ' (This causes the For...Next Loop to skip 
                    ' checking the Text of the ComboBox that is calling 
                    ' the Sub as it would show the name having
                    ' been selected before when if fact it has not.)

                    If ctl.Text = Scc.Text Then
                        ' If the other ComboBox.Text is the same as the 
                        ' ComboBox that is calling the Sub in the 
                        ' MouseMove Event

                        ' Tell the User that there is a problem with their 
                        ' selection.

                        MessageBox.Show("The Name you selected has " & _
                          "already been entered." & Environment.NewLine &  _
                          "Please select another Name.", Me.Text, _
                          MessageBoxButtons.OK, MessageBoxIcon.Information)

                        Scc.Text = "Select Again"

                        ' Change the Text of the ComboBox so the User can see 
                        ' which place ComboBox they need to re-select 
                        ' a Name from.

                        Scc.Focus()  ' Set Focus to the ComboBox

                        Exit Sub  ' Exit the Sub
                    End If
                End If
            End If
        Next

        Ecc.Enabled = True
        ' The name does not match any of the previously selected Names, 
        ' so let the User move onto the next step
    End If
End Sub

The up side of all this is that my project once again checks for names being selected twice. The down side is that by resorting to moving the mouse is that it creates a weird Mouse movement. I ran an example for a couple of people and they didn't notice the jump of the Mouse, but because I know it is going to happen I really find it something that is glaringly obvious.

Advertisement

We launched new web site that aggregates content from variuos Visual Basic related resources - http://vbfeeds.com.

Subscribe to the site's aggregated RSS feed of many top VB bloggers, screened for content (so you don't get random entries about the blogger's dog or something) - a good way to keep up with what's going on in the Visual Basic community.

Web site link - http://vbfeeds.com

Aggregated RSS link - http://feeds.feedburner.com/vbfeeds

Launch announcement link - SergeB Blog post

http://vbfeeds.com
Advertisement

We encourage you to pass this issue of
.net.devcity.weekly on to anyone you know with an interest in .NET technology and News You Can Compile

Manage Your Subscription Here.

You are currently subscribed as '*EMAIL*' to .net.devcity.weekly.

Click here to unsubscribe.

Thanks for reading!

Contact:
vbCity.com, LLC
4957 Lakemont Blvd SE C4 #331
Bellevue, WA 98006


DevCity.NET is hosted by FullControl.NET

Copyright vbCity.com, LLC 2003. All Rights Reserved.