I am implementing the system menu (Restore, Move, Size...) on a borderless window, and I want the mouse cursor to move to the center of the Window when size or move is selected.
Ideally in VB but C# is fine as well.
You can use the SetCursorPos function, something like:
Declare Function SetCursorPos& Lib "user32" (ByVal p As Point)
'...
dim p as point
p.x = 100
p.y = 200
SetCursorPos p
A few tweaks and it seems to work:
Private Declare Function SetCursorPos Lib "user32" (ByVal x As Int32, ByVal Y As Int32) As Int32
...
With Win
Dim left As Int32 = CInt(.Left + .Width - CURSOR_OFFSET_MEDIUM)
Dim top As Int32 = CInt(.Top + .Height / 2)
SetCursorPos(left, top)
End With
Related
I want to resize a custom window, so windowstyle=none.
For that I do not want to use some Open-Sourelib.
So I found this article via google.
After I changed the code a bit, since i want to use a button instead of a rectangle for resizing the code looks like this:
Private bottomResize As Boolean = False
Private initBtmY As Double
Private Sub BottomResizeRect_MouseEnter _
(ByVal sender As Object, ByVal e As _
System.Windows.Input.MouseEventArgs) _
Handles btResizeAndFold.MouseEnter
bottomResize = False
'Console.WriteLine("Mouse Enter called")
End Sub
Dim boing As Boolean = False
Private Sub BottomResizeRect_MouseLeftButtonDown _
(ByVal sender As Object, ByVal e As _
System.Windows.Input.MouseButtonEventArgs) _
Handles btResizeAndFold.PreviewMouseLeftButtonDown
bottomResize = True
boing = True
'Console.WriteLine("Mouse left down called")
'Get the initial Y coordinate
'cursor location on our window
initBtmY = e.GetPosition(Me).Y
End Sub
Private Sub BottomResizeRect_MouseLeftButtonUp _
(ByVal sender As Object,
ByVal e As System.Windows.Input.MouseButtonEventArgs) _
Handles btResizeAndFold.PreviewMouseLeftButtonUp
'Console.WriteLine("Mouse left up called")
bottomResize = False
btResizeAndFold.ReleaseMouseCapture()
End Sub
Private Sub BottomResizeRect_MouseMove _
(ByVal sender As Object, ByVal e As _
System.Windows.Input.MouseEventArgs) _
Handles btResizeAndFold.PreviewMouseMove
'Get the new Y coordinate cursor location
Dim newBtmY As Double = e.GetPosition(Me).Y
'Get the change between the initial and
'new cursor location
Dim diff As Double = initBtmY - newBtmY
'Minimum window height
Dim minHeight As Integer = 200
Dim differnceConstant = 5
If bottomResize = True And (diff > differnceConstant Or diff < (differnceConstant * -1)) Then
'Let our rectangle capture the mouse
btResizeAndFold.CaptureMouse()
Dim newHeight = e.GetPosition(Me).Y - diff
If newHeight > minHeight Then
Me.Height = newHeight
End If
End If
End Sub
The problem now is, that if i try to resize my window by pressing the left mouse button and then drag the mouse, the increase/decrease of the height of my window is not synchonosly to the movement of my mouse cursor, so the question is: how to make the movement of the mouse sychronos to growth of the window
Instead of Button you could use Thumb, which provide with DragDelta Event that suits your requirement:
https://wpf.2000things.com/2012/12/19/715-using-the-thumb-control-to-drag-objects-on-a-canvas/
That way you dont need to capture the mouse(you shouldnt've put the CaptureMouse in the PreivewMouseMove anyway, it will do that a lot).
And just set the height as the current height + the delta Y.
I'm trying to resize and save the 3 images as defined in the Page_load event.
Within method ResizeAndSave I have 2 methods I'm trying: FastResize and SlowResize.
When I uncomment the FastResize codeline: IMAGE 1 and 2 are saved and resized correctly. IMAGE 3 however, is saved in dimensions 625x441px and so does not respect the 200x200 box I want it to resize to.
When I instead use the SlowResize codeline: IMAGE 1 and 2 are again saved and resized correctly. IMAGE 3 however, is not saved at all.
No errors are thrown in my code. I will import images from a variety of sources so it's critical my code works on a wide range of image formats. And apparently there's something special about IMAGE 3 and I don't know what it is or how to handle it.
Here's my full code, you should be able to just copy/paste it and test it for yourself:
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.IO
Imports System.Xml
Imports System.Data.SqlClient
Imports System.Net
Imports System.Windows.Media.Imaging
Imports System.Windows.Media
Partial Class importfeeds
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'IMAGE 1
ResizeAndSave(200, 200, "https://upload.wikimedia.org/wikipedia/commons/8/82/Dell_Logo.png")
'IMAGE 2
ResizeAndSave(200, 200, "https://upload.wikimedia.org/wikipedia/commons/d/d8/Square-1_solved.jpg")
'IMAGE 3
ResizeAndSave(200, 200, "http://cdn2.emobassets.eu/media/catalog/product/1/1/1116220.jpg")
End Sub
Private Sub ResizeAndSave(ByVal maxWidth As Integer, ByVal maxHeight As Integer, ByVal imageURL As String)
Dim imgRequest As WebRequest = WebRequest.Create(imageURL)
Dim imgResponse As WebResponse = imgRequest.GetResponse()
Dim streamPhoto As Stream = imgResponse.GetResponseStream()
Dim memStream As New MemoryStream
streamPhoto.CopyTo(memStream)
memStream.Position = 0
Dim bfPhoto As BitmapFrame = ReadBitmapFrame(memStream)
Dim newWidth, newHeight As Integer
Dim scaleFactor As Double
If bfPhoto.Width > maxWidth Or bfPhoto.Height > maxHeight Then
If bfPhoto.Width > maxWidth Then
scaleFactor = maxWidth / bfPhoto.Width
newWidth = Math.Round(bfPhoto.Width * scaleFactor, 0)
newHeight = Math.Round(bfPhoto.Height * scaleFactor, 0)
End If
If newHeight > maxHeight Then
scaleFactor = maxHeight / newHeight
newWidth = Math.Round(newWidth * scaleFactor, 0)
newHeight = Math.Round(newHeight * scaleFactor, 0)
End If
End If
Dim bfResize As BitmapFrame = FastResize(bfPhoto, newWidth, newHeight)
'Dim bfResize As BitmapFrame = SlowResize(bfPhoto, newWidth, newHeight, BitmapScalingMode.Linear)
Dim baResize As Byte() = ToByteArray(bfResize)
Dim strThumbnail As String = Guid.NewGuid.ToString() + ".png"
Dim saveToPath As String = Server.MapPath(ConfigurationManager.AppSettings("products_photospath")) + "\49\" + strThumbnail
File.WriteAllBytes(saveToPath, baResize)
End Sub
Private Shared Function FastResize(bfPhoto As BitmapFrame, nWidth As Integer, nHeight As Integer) As BitmapFrame
Dim tbBitmap As New TransformedBitmap(bfPhoto, New ScaleTransform(nWidth / bfPhoto.PixelWidth, nHeight / bfPhoto.PixelHeight, 0, 0))
Return BitmapFrame.Create(tbBitmap)
End Function
'http://weblogs.asp.net/bleroy/resizing-images-from-the-server-using-wpf-wic-instead-of-gdi
Public Shared Function SlowResize(photo As BitmapFrame, width As Integer, height As Integer, scalingMode As BitmapScalingMode) As BitmapFrame
Dim group = New DrawingGroup()
RenderOptions.SetBitmapScalingMode(group, scalingMode)
group.Children.Add(New ImageDrawing(photo, New Windows.Rect(0, 0, width, height)))
Dim targetVisual = New DrawingVisual()
Dim targetContext = targetVisual.RenderOpen()
targetContext.DrawDrawing(group)
Dim target = New RenderTargetBitmap(width, height, 96, 96, PixelFormats.[Default])
targetContext.Close()
target.Render(targetVisual)
Dim targetFrame = BitmapFrame.Create(target)
Return targetFrame
End Function
Private Shared Function ToByteArray(bfResize As BitmapFrame) As Byte()
Using msStream As New MemoryStream()
Dim pbdDecoder As New PngBitmapEncoder()
pbdDecoder.Frames.Add(bfResize)
pbdDecoder.Save(msStream)
Return msStream.ToArray()
End Using
End Function
Private Shared Function ReadBitmapFrame(streamPhoto As Stream) As BitmapFrame
Dim bdDecoder As BitmapDecoder = BitmapDecoder.Create(streamPhoto, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None)
Return bdDecoder.Frames(0)
End Function
End Class
UPDATE 1
#Hans Passant: Both your suggestions on filenaming and pixelWidth usage are spot on and helped me run this code successfully on the 3 images in the Page_load event.
I updated my original code.
However, when I run this code as part of my actual application, where I import ~100 images from a feed. The new code fails with an out of memory exception when it tries to process IMAGE 3. This happens for both FastResize and SlowResize methods. Is there something in my code or in the image in question that would cause this increase in memory usage, maybe a leak somewhere or an inefficient resizing method I use?
I have a lot of memory available on my machine, so would be very surprised if that were the problem, although I do see a big increase in the System and compressed memory (to 1.1GB) task in my Windows task manager. And still, this much memory usage would have me believe that there's something wrong in my code.
What can it be?
IMAGE 3 however, is saved in dimensions 625x441px
That is because the image is slightly different from the other ones, its DPI (dots per inch) is 300 instead of 96. Its size in pixels is 3071 x 2172 but you are using the Width and Height properties, the size in inches with a unit of 1/96" which is 982.72 x 695.04 for this image. Fix this by using the PixelWidth and PixelHeight properties instead:
Dim tbBitmap As New TransformedBitmap(bfPhoto,
New ScaleTransform(nWidth / bfPhoto.PixelWidth, nHeight / bfPhoto.PixelHeight, 0, 0))
IMAGE 3 however, is not saved at all
That doesn't add up completely, but you do have a critical bug in this statement:
Dim strThumbnail As String = "success" + Date.Now.Second.ToString + ".png"
This name is not sufficiently unique to ensure that you don't overwrite an existing file. And if the code is "fast" then Date.Now.Second will have the same value and your code overwrites a previous written image file. Note how this bug won't repro when you debug, that makes the code artificially slower and the second will be different.
You'll need a better way to name the file, Guid.NewGuid.ToString() is a very good way for example, guaranteed to be unique. Or use a simple counter that you increment for each image. You do need to focus on cleanup.
I have a combobox that's being populated from the SQL-SERVER with a list of names. What I'm trying to do is, let the user click on the drop down and show all names without scrolling down.
assuming the font of combo is the same as the forms one
Option Explicit
Private Declare Function MoveWindow Lib "user32" _
(ByVal hWnd As Long, ByVal x As Long, ByVal y As Long, _
ByVal cx As Long, ByVal cy As Long, ByVal updt As Long) As Long
Private Sub Form_Load()
Dim I As Long
Me.ScaleMode = vbPixels
With Combo1
MoveWindow .hWnd, .Left, .Top, .Width, .Height + (Me.TextHeight("W") * 11), 0 'why 11 and not 10? i realy don't know right now
End With
For I = 1 To 20
Combo1.AddItem "Item " & I
Next I
End Sub
I would like to transparent red color form background of visual basic 6 program.
I use this code to make the background of the form transparent:
Option Explicit
Private Const GWL_EXSTYLE As Long = (-20)
Private Const LWA_COLORKEY As Long = &H1
Private Const LWA_Defaut As Long = &H2
Private Const WS_EX_LAYERED As Long = &H80000
Private Declare Function GetWindowLong Lib "user32" Alias _
"GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias _
"SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Private Declare Function SetLayeredWindowAttributes Lib "user32" _
(ByVal hWnd As Long, ByVal crKey As Long, ByVal bDefaut As Byte, _
ByVal dwFlags As Long) As Long
Private Sub Form_Load()
Me.BackColor = RGB(254,0,0)
Transparency Me.hWnd, Me.BackColor, 255
End Sub
Private Sub Transparency(ByVal hWnd As Long, ByVal lngTransparentColor As Long, _
ByVal bytTransparency As Byte)
Dim lngwindowstyle As Long
lngwindowstyle = GetWindowLong(hWnd, GWL_EXSTYLE)
If (lngwindowstyle And WS_EX_LAYERED) <> WS_EX_LAYERED Then
SetWindowLong hWnd, GWL_EXSTYLE, lngwindowstyle Or WS_EX_LAYERED
End If
SetLayeredWindowAttributes hWnd, lngTransparentColor, bytTransparency, _
LWA_COLORKEY Or LWA_Defaut
End Sub
But as you can see in the picture the red noise remains :
How can I remove this noise?
I saved the picture with .png extension and use AlphaImageControl.ocx to show it.
The red noise is removed but a red line under form remains :
As the commenters already said, your "red" isn't always the same red. The line under the form remains, if you look closely you can see it: the red lines are fading from red to black. So even if your left pixel is 254,0,0 the next ones are not. I recommend using a blank/real transparent background, png offers you that :)
How do I know if an element in my WPF application, is hidden by another window of any application
Here are my example how I get information about open windows on the screen. For example: Is my application on top.
(the basic code I am learned in http://www.codeproject.com/Articles/19529/Is-My-Application-on-Top)
Declare Function GetTopWindow Lib "user32" Alias "GetTopWindow" (ByVal hwnd As Integer) As Integer
Declare Function GetNextWindow Lib "user32" Alias "GetWindow" (ByVal hwnd As Integer, ByVal wFlag As Integer) As Integer
Declare Function IsWindowVisible Lib "user32" Alias "IsWindowVisible" (ByVal hwnd As Integer) As Boolean
Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Integer, ByVal lpString As String, ByVal cch As Integer) As Integer
Declare Function GetWindowRect Lib "user32" Alias "GetWindowRect" (ByVal hwnd As IntPtr, ByRef pwi As Rect) As Boolean
Function IsOnTop(ByVal hwnd As Integer) As Boolean
Dim i As Integer = GetTopWindow(0)
Dim x As Integer = 1
Dim s As String
Do
i = GetNextWindow(i, 2) ' Find next window in Z-order
If i = hwnd Then
Exit Do
Else
If i = 0 Then ' Never find any window match the input handle
Return False
End If
End If
If IsWindowVisible(i) = True Then
s = Space(256)
If GetWindowText(i, s, 255) <> 0 Then
' Very important to prevent confusing of BalloonTips and ContextMenuStrips
x += 1
End If
End If
Loop
' x is Z-order number
If x = 1 Then
Return True
Else
Return False
End If
End Function
Public Function GetWindowText(ByVal hWnd As IntPtr) As String
Dim s = Space(256)
GetWindowText(hWnd, s, 255)
Return s.ToString()
End Function
Function GetRectWindow(hwnd As Integer) As Rect
Dim rc As Rect
GetWindowRect(hwnd, rc)
Return rc
End Function
I need to know the width & height of other windows. Without this data, I still can not know about an element if it is hidden to the user. For example, in my application, I have a window that contains two DataGrid's, one of which may be hidden by other application.
The problem is, Although the GetRectWindow method returns this data, but, for example, it gives in Width property = 4.09332988076806E-311 and it should be 350. To my knowledge, it uses Twips unit. I converted it to pixel unit, but the result I got is an infinite number -0.
Here is a way :
Compute bounds of your visual relative to root visual (Visual.TransformToAncestor)
Compute bounds of your visual relative to screen (native GetWindowRect & GetClientRect)
Enumerate all top level windows (native EnumWindows)
Check for each windows if it's visible and if it overlaps the bounds of your visual (native GetWindowRect)