Drawing digits/graphics directly to the screen? - windows

I'm putting together a small program in Visual Basic Express 2010, and part of it is to take a delayed screen shot.
I've got the main code working, I've got Visual Basic delaying taking the screen shot with System.Threading.Thread.CurrentThread.Sleep(5000), but what I'm looking for is a way to draw directly to the screen the number of seconds remaining.
You know how in Windows, in the Display Properties under Settings, when you click on Identify you get a huge number displayed on each monitor?
I'm trying to recreate that, with the number counting down until the screen shot is taken, giving the user plenty of notification to get their required applications in focus for the screen shot.
Is it possible to do this? Or is it something that will take a heck of a lot of coding?
Many thanks for any help you can offer

Create a Label control in a Form and use something like the following to make it transparent:
Me.TransparencyKey = Color.Gray ' or any other color.
Me.BackColor = TransparencyKey
Me.FormBorderStyle = FormBorderStyle.None
will make something like this:
To make your window transparent to mouse, PInvoke GetWindowLong and SetWindowLong:
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function GetWindowLong( _
ByVal hWnd As IntPtr, _
ByVal nIndex As Integer) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function SetWindowLong( _
ByVal hWnd As IntPtr, _
ByVal nIndex As Integer, _
ByVal dwNewLong As IntPtr) As Integer
End Function
Then in your Form_Load() add the following:
Dim hwnd As IntPtr = Me.Handle
Dim extendedStyle As Integer = GetWindowLong(hwnd, GWL_EXSTYLE)
SetWindowLong(hwnd, GWL_EXSTYLE, extendedStyle Or WS_EX_TRANSPARENT)
Constants:
Const WS_EX_TRANSPARENT As Integer = &H20
Const GWL_EXSTYLE As Integer = -20

Related

How Do I Turn On/Off X-Mouse in Tweak UI?

I'm attempting to create a VB6 executable (not sure of the proper syntax) that will toggle the X-Mouse option in Tweak UI under Windows 98SE. Ideally, I would like to have two scripts - one that turns it off (regardless of its state) and one that turns it on (again, regardless of its state).
I have been able to open the TweakUI control panel with the code below.
Private Sub Form_Load()
Call Shell("rundll32.exe shell32.dll,Control_RunDLL tweakui.cpl", vbNormalFocus)
End Sub
If possible, I would like it to do it without opening the TweakUI control panel.
As far as I can tell, changing the registry setting doesn't work as I would have to reboot the computer for that to take effect.
I have Registry Monitor 7.04 running. It captures the following:
Path: C:\WINDOWS\RUNDLL32.EXE
Command Line: "C:\WINDOWS\RUNDLL32.EXE" "C:\WINDOWS\SYSTEM\TWEAKUI.CPL", Tweak UI
Other: hKey: 0xC2A066F0
Honestly, I'm not sure how to move forward.
Not sure the best way to show progress on this, I'll just edit.
This code is very close.
Private Declare Function SystemParametersInfo Lib "user32" Alias _
"SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, _
ByRef lpvParam As Any, ByVal fuWinIni As Long) As Long
Const SPI_SETACTIVEWINDOWTRACKING = 4097
'Click on this button to Activate XMouse
Private Sub Command1_Click()
SystemParametersInfo SPI_SETACTIVEWINDOWTRACKING, 0, True, 0
End Sub
'Click on this button to Deactivate XMouse
Private Sub Command2_Click()
SystemParametersInfo SPI_SETACTIVEWINDOWTRACKING, 0, False, 0
End Sub
Button 1 works correctly and Activates XMouse. But button two does not deactivate it.
SPI_SETACTIVEWINDOWTRACKING is the parameter that does this.
systemparametersinfo is the function call that gets or sets settings like this. See https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-systemparametersinfoa
There is sample code using systemparametersinfo that changes the wallpaper. https://winsourcecode.blogspot.com/2019/06/changewallpaper.html
Thank you to all of the input. I was able to solve this problem.
Private Declare Function SystemParametersInfo Lib "user32" Alias _
"SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, _
ByVal lpvParam As Boolean, ByVal fuWinIni As Long) As Long
Const SPI_SETACTIVEWINDOWTRACKING = 4097
Private Sub Command1_Click()
retVal = SystemParametersInfo(SPI_SETACTIVEWINDOWTRACKING, 0, True, 0)
End Sub
Private Sub Command2_Click()
retVal = SystemParametersInfo(SPI_SETACTIVEWINDOWTRACKING, 0, False, 0)
End Sub
In addition to the help here, I stumbled upon a few gems that gave me what I needed.
Control the mouse speed under Windows 98 / 2000
and
Controling Active Window Tracking
A couple things of note. I had to include this or else nothing happened:
Const SPI_SETACTIVEWINDOWTRACKING = 4097
Also, the 3rd parameter was
ByRef lpvParam As Boolean
Instead of
ByVal lpvParam As Boolean
I was passing a pointer to a pointer instead of a pointer to a value

VB6 mouse hook to capture a control a user clicks

I have a keyboard hook that listens for [shift] + [F12] key button press to activate an edit mode in my program. By edit mode, I mean that any form that is inactive in the program window is disabled and focus is set to the active window. Furthermore, I alter the GUI to reflect that the user is running edit mode.
The purpose is of this all is to customize specific form controls that a user clicks on (e.g If they click on a label or combobox, a user would be able to edit the data that populates this information from a database). What I am really searching for is the ability to access the control name of the control that a user clicks on in the active form, DYNAMICALLY (without setting events on each form). Therefore, once a user clicks on a control such as a label, combo box, listview or listbox (on the active form), I would like to capture the control name clicked and pass that to another form that will handle the editing of this control.
You don't need to go to the trouble of using the API for what you want to do. All of the controls you mention expose a Click event. (If the control you want to use doesn't have a Click event, it almost certainly has a MouseDown event which will work just as well.) Just write a sub that takes the control as an argument and passes what info you want to the other form. Then in each of the controls (you can use control arrays for controls of the same type), call this sub. Something like this:
Sub DoTheWork(cCtl As Control)
Form2.CallSomeMethod(cCtl) 'Passes a reference to the entire control
Form2.CallSomeOtherMethod(cCtl.Name) 'Just passes the name
End Sub
Sub Command1_Click()
DoTheWork Command1
End Sub
Sub Label1_Click(Index As Integer) 'control array
DoTheWork Label1(Index)
End Sub
Now, if you really want to get involved in using SetWindowsHookEx and all that, here's a bit of annotated code that you can use to figure it out. This code allows you to change fonts on the MsgBox function, by substituting itself for any MsgBox call. (FYI, Microsoft implemented "CBT hooking" to support computer-based training back in the day, hence the term.)
'This code allows font changes and various other format customizations of the standard VB6 MsgBox dialog box. It
'uses CBT hooking to intercept an VB6-internal window call. In this case, it intercepts a MsgBox call, then gets
'a handle to the MsgBox window as well as its various child windows (the label containing the message text, any
'buttons, and an icon if it exists). It then resizes the window to accommodate the message text and other windows,
'and repositions the icon and any command buttons. Finally, it positions the msgbox window in the center of the
'screen.
'General Note: notes are above the line of code to which they apply.
Option Explicit
' Window size and position constants
Private Const ICON_WIDTH As Integer = 32
Private Const BTN_WIDTH As Integer = 75
Private Const BTN_HEIGHT As Integer = 23
Private Const BTN_SPACER As Integer = 6 ' Space between 2 buttons
Private Const STW_OFFSET As Integer = 12 ' Standard window offset, minimum distance one window can be from
' the edge of its container
' SendMessage constants that we will use
Private Const WM_SETFONT = &H30
Private Const WM_GETTEXT = &HD
' Necessary constants for CBT hooking
Private Const HCBT_CREATEWND = 3
Private Const HCBT_ACTIVATE = 5
Private Const WH_CBT = 5
' Working variables that require module-wide scope
Private hHook As Long
Private myFont As IFont
Private cPrompt As String
Private hwndStatic As Long
Private ButtonHandles() As Long
Private xPixels As Long
Private yPixels As Long
Private isIcon As Boolean
' The API Type declarations we need
Private Type SIZE
cx As Long
cy As Long
End Type
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
'GETTEXT needs a String argument for lParam, SETFONT needs an Any argument there, hence 2 declarations for SendMessageA
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function SendMessageS Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Private Declare Function GetClientRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
' Wrapper for the normal MsgBox function
Public Function myMsgBox(Prompt As String, Buttons As VbMsgBoxStyle, ByVal fSize As Integer, ByVal fBold As Boolean, ByVal fItalic As Boolean, ByVal fULine As Boolean, fFaceName As String, Optional Title As String, Optional HelpFile As String, Optional Context As Long, Optional x As Long, Optional y As Long) As Long
'x and y arguments are optional and are in twips. If not specified, msgbox will use default window sizes
'and positions, which work fine if you are using default font sizes. If you aren't they may not.
cPrompt = Prompt
Set myFont = New StdFont
With myFont ' We can make whatever adjustments we like here to the font
.SIZE = fSize
.Bold = fBold
.Italic = fItalic
.Underline = fULine
.Name = fFaceName
End With
'Convert x and y arguments to pixels from twips. (Twips are the same size no matter what the screen resolution; pixels aren't.)
If Not IsMissing(x) Then
xPixels = Int(x / Screen.TwipsPerPixelX)
End If
If Not IsMissing(y) Then
yPixels = Int(y / Screen.TwipsPerPixelY)
End If
'Set up the hook to catch windows messages, call CBTProc when there is one
hHook = SetWindowsHookEx(WH_CBT, AddressOf CBTProc, App.hInstance, 0)
'This will call CBTProc, passing the handle of the MsgBox window to the wParam argument.
myMsgBox = MsgBox(Prompt, Buttons, Title, HelpFile, Context)
End Function
Private Function CBTProc(ByVal lMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim i As Integer
Dim statX As Integer 'X dimension of static (text) window
Dim statY As Integer 'Y dimension of same
Dim cLeft As Integer 'Current Left value for current button, used to position buttons along x axis
Dim rc As RECT 'Used with GetClientRect
If lMsg = HCBT_ACTIVATE Then
'Immediately unhook (we have the event we're looking for, and don't want to handle any more CBT events)
UnhookWindowsHookEx hHook
'Call EnumChildWindowProc once for each window that is contained in the MsgBox (each button and frame is a child window)
EnumChildWindows wParam, AddressOf EnumChildWindowProc, 0
'Reinitialize the static buttoncount variable, see the notes in the proc
EnumChildWindowProc 0, 1
'Should always be true, but this prevents an abend if for some reason we fail to get the text window
If hwndStatic Then
'If the x parameter has been supplied to the main wrapper, then xPixels <> 0
If xPixels <> 0 Then
With Screen
'Center the MsgBox window in the screen
SetWindowPos wParam, 0, (.Width / .TwipsPerPixelX - xPixels) / 2, _
(.Height / .TwipsPerPixelY - yPixels) / 2, xPixels, yPixels, 0
End With
'Analogous to the ScaleWidth and ScaleHeight properties. Client rectangle's dimensions are
'returned to the rc type and exclude the dimensions of the title bar and the borders.
GetClientRect wParam, rc
'Calculate x and y values for text window. If there's an icon, we need to reduce the size of the
'text window by the width of the icon plus a standard offset value.
statX = rc.Right - rc.Left - STW_OFFSET * 2 - ((isIcon And 1) * (ICON_WIDTH + STW_OFFSET))
statY = rc.Bottom - rc.Top - BTN_HEIGHT - STW_OFFSET * 2
'We need to position the text window along the x axis such that it's a standard offset from the left
'border of the msgbox, plus the width of the icon and another standard offset if the icon exists.
SetWindowPos hwndStatic, 0, STW_OFFSET + (isIcon And 1) * (ICON_WIDTH + STW_OFFSET), STW_OFFSET, statX, statY, 0
isIcon = 0
'Loop through the button handles, calculating the left border position each time.
For i = 0 To UBound(ButtonHandles)
'Current left border is half the container window's width, less the width of half the total
'number of buttons, plus the offset of the current button in the array.
cLeft = Int(xPixels / 2 + BTN_WIDTH * (i - (UBound(ButtonHandles) + 1) / 2))
'Modify the above to add button spacer widths.
cLeft = cLeft + BTN_SPACER * (i - (UBound(ButtonHandles) - 1) + (UBound(ButtonHandles) Mod 2) / 2)
'The Y value is 1 standard offset more than the height of the text window.
SetWindowPos ButtonHandles(i), 0, cLeft, statY + STW_OFFSET, BTN_WIDTH, BTN_HEIGHT, 0
Next
End If
SendMessage hwndStatic, WM_SETFONT, myFont.hFont, True
End If
End If
CBTProc = 0 ' allow operation to continue
End Function
Private Function EnumChildWindowProc(ByVal hChild As Long, ByVal lParam As Long) As Long
Static ButtonCount As Integer
Dim sLen As Integer
Dim wClass As String
Dim wText As String
Dim rc As RECT
If lParam Then
ButtonCount = 0 'See the direct call of this proc in CBTProc: resets the ButtonCount variable to 0
Exit Function
End If
wClass = String(64, 0)
'look up the type of the current window
sLen = GetClassName(hChild, wClass, 63)
wClass = Left(wClass, sLen)
'We have either one or two static windows: optionally the icon (the first window if it's there) and the
'text window (analogous to a label control).
If wClass = "Static" Then
'If we already have the text window's handle, we don't need to do this anymore.
If Not hwndStatic Then
'Find out if the current window's text value is the same as the text passed in to the cPrompt
'argument in the main wrapper function. If it is, it's the text window and we store the handle
'value in hwndStatic. If it isn't, then it's an icon and we set the isIcon flag.
wText = String(Len(cPrompt) + 1, 0)
sLen = SendMessageS(hChild, WM_GETTEXT, 255, wText)
wText = Left(wText, sLen)
If wText = cPrompt Then
hwndStatic = hChild
Else
isIcon = True
End If
End If
ElseIf wClass = "Button" Then
'Store the button's handle in the ButtonHandles array
ReDim Preserve ButtonHandles(ButtonCount)
ButtonHandles(ButtonCount) = hChild
ButtonCount = ButtonCount + 1
End If
EnumChildWindowProc = 1 ' Continue enumeration
End Function

VBS send mouse clicks?

I need send mouse clicks from VBS. Like SendKeys. I have searched whole google, it seems there is no such function for VBS. Can you give me some solution?
Here is a routine to send a left or right click to a window (using relative references) in VBA for Excel. Similar to AppActivate, you just need the window title.
The arguments when you call the SendClick routine are:
Window Title (String)
Buttons (1 = Left, 2 = Right, -1 = Move mouse only; no click)
x (Relative position to window Left)
y (Relative position to window Top)
Enjoy!
'Declare mouse events
Public Declare Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long
Public Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As Long)
Public Const MOUSEEVENTF_LEFTDOWN = &H2
Public Const MOUSEEVENTF_LEFTUP = &H4
Public Const MOUSEEVENTF_RIGHTDOWN As Long = &H8
Public Const MOUSEEVENTF_RIGHTUP As Long = &H10
'Declare sleep
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
' Window location
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function GetWindowRect Lib "user32" (ByVal hWnd As Long, lpRect As RECT) As Long
Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Public Function WindowHandle(ByVal sTitle As String) As Long
WindowHandle = FindWindow(vbNullString, sTitle)
End Function
Public Sub SendClick(sWnd As String, b As Integer, x As Long, y As Long)
Dim pWnd As Long, pRec As RECT
pWnd = WindowHandle(sWnd)
GetWindowRect pWnd, pRec
SetCursorPos pRec.Left + x, pRec.Top + y
Sleep 50
If b = 2 Then
mouse_event MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0
Sleep 50
mouse_event MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0
ElseIf b <> -1 Then
mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0
Sleep 50
mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0
End If
End Sub
It's not possible with VBScript alone. You'll need to use a third-party tool like nircmd. You can use its setcursor, setcursorwin, movecursor, and sendmouse commands to manipulate the mouse.
For example, here's how to move the cursor to a screen coordinate (measured from the top left) and perform a right-click:
With CreateObject("WScript.Shell")
.Run "nircmd setcursor 100 100", 0, True
.Run "nircmd sendmouse right click", 0, True
End With
See the documentation for parameter information.
Try
Dim x
set x=createobject("wscript.shell")
x.sendkeys"{CLICK LEFT,50,60}"
or
x.SendKeys("+{F10}") 'for a right click
If neither of those work for you I would suggest using something like Autoit or autohotkey, using AutoHotKey you could write a macro that does the clicking and then call the script from your VBScript.
VBS is a script, not an application; VBScripts can call other applications or Component Objects to access elements of the host environment, just like batch files; eg. FileSystemObject to manipulate files.
There isn't one provided for mouse, so to move mouse or send mouse clicks, you'd need to call some app or COM object to do it, or make one.
Some apps that can manipulate the mouse are MSWord & MSExcel (via WinAPI calls), NirCmd, AutoIt, AutoHotKey, etc
Here's a VBApp example that calls functions of the User Component: user32.dll:
(Notice how the arguments are formatted before being sent to the DLL. This is not possible in VBS or batch files since they can only pass Strings as args; some functions expect data types eg. Int32, window handles or object references)
Option Strict On
Option Explicit On
Option Infer On
Imports System.Runtime.InteropServices
Public Class Mousing
Private Declare Auto Sub mouse_event Lib "user32" (ByVal dwFlags As Int32, ByVal dx As Int32, ByVal dy As Int32, ByVal cButtons As Int32, ByVal dwExtraInfo As IntPtr)
Private Const MOUSEEVENTF_LEFTDOWN As Int32 = &H2
Private Const MOUSEEVENTF_LEFTUP As Int32 = &H4
Private Const MOUSEEVENTF_RIGHTDOWN As Long = &H8
Private Const MOUSEEVENTF_RIGHTUP As Long = &H10
<StructLayout(LayoutKind.Sequential)>
Private Structure RECT
Public Left As Integer
Public Top As Integer
Public Right As Integer
Public Bottom As Integer
End Structure
<DllImport("user32.dll")> _
Private Shared Function GetWindowRect(ByVal hWnd As IntPtr, ByRef lpRect As RECT) As Boolean
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto, EntryPoint:="FindWindow")> _
Private Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
End Function
<DllImport("user32.dll", CharSet:=CharSet.Ansi, SetLastError:=True, ExactSpelling:=True)> _
Private Shared Function SetForegroundWindow(ByVal hwnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
' find the window
Dim hWnd As IntPtr = FindWindow(Nothing, "Some Window")
' check if window found
If hWnd.Equals(IntPtr.Zero) Then
MessageBox.Show("Window Not Found!", "Aborting", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Return ' exit
Else
' bring the window to the foreground
SetForegroundWindow(hWnd)
' get the windows size and location
Dim r As New RECT
GetWindowRect(hWnd, r)
'Move the cursor to the windows location plus our offset (x + 50 , y + 100)
Windows.Forms.Cursor.Position = New System.Drawing.Point(r.Left + 50, r.Top + 100)
' To move relative to screen, just enter coordinates above without offsetting
' click the left mouse button at the current mouse position
mouse_event(MOUSEEVENTF_LEFTDOWN + MOUSEEVENTF_LEFTUP, 0, 0, 0, IntPtr.Zero)
End If
End Sub
End Class
The following is a VBScript calling AutoIt to move mouse & click:
Set oAutoIt = WScript.CreateObject("AutoItX.Control")
set oShell = CreateObject("WScript.Shell")
oAutoIt.MouseMove x,y,0
WScript.Sleep 500
oAutoIt.MouseClick($MOUSE_CLICK_PRIMARY)
References:
http://www.vbforums.com/showthread.php?672196-RESOLVED-SetCursorPos
http://www.ericphelps.com/batch/rundll/
https://www.dostips.com/forum/viewtopic.php?t=3931
https://support.microsoft.com/en-au/help/152969/visual-basic-procedure-to-get-set-cursor-position
https://microsoft.public.scripting.vbscript.narkive.com/ZO09Cxnz/moving-mouse-pointer-with-vbs-file

VB6 Disable system beep sound when arrow up/down is pressed inside rich text box?

I have a Rich Text Box control. It has no scroll bars, cause I am using Mouse Wheel module to capture Mouse Wheel events.
When the rich text box is selected and mouse wheel is rotated up/down it sends keys {UP} and {DOWN} to they rich text box to "mimic" the scroll effect.
However, when you are at the beginning or at the ending of the text box content (e.g there's nothing to scroll anymore), there's annoying beep system sound playing. I need to disable this, any ideas how to do that ?
Already tried adding this code in the rich text box's keypress event:
If KeyAscii = 38 Or KeyAscii = 40 Then
KeyAscii = 0
End If
Doesn't work. Don't know why it just doesn't work when it is supposed to be working.
Use the KeyDown event instead of KeyPress, and disable the KeyCode only if the cursor is located at the first/last line to prevent disabling the arrow keys (up/down) completely.
First you need to add the following to the declarations:
Private Declare Function SendMessage Lib "USER32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long
Private Const EM_LINEFROMCHAR = &HC9
Private Const EM_GETLINECOUNT = &HBA
Private Function GetCurrentLine(Txt As RichTextBox) As Long
GetCurrentLine = SendMessage(Txt.hWnd, EM_LINEFROMCHAR, Txt.SelStart, 0&) + 1
End Function
Private Function GetLineCount(Txt As RichTextBox) As Long
GetLineCount = SendMessage(Txt.hWnd, EM_GETLINECOUNT, 0&, 0&)
End Function
Then use the KeyDown event as described:
Private Sub RichTextBox1_KeyDown(KeyCode As Integer, Shift As Integer)
If KeyCode = vbKeyUp Then
If GetCurrentLine(RichTextBox1) = 1 Then KeyCode = 0
ElseIf KeyCode = vbKeyDown Then
If GetCurrentLine(RichTextBox1) = GetLineCount(RichTextBox1) Then KeyCode = 0
End If
End Sub
Of course you'll need to replace RichTextBox1 with the name of your RichTextBox.
Hope that helps :)
Outside of a function/sub
Public Declare Function SendMessageByVal Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
In your sub/function
Ret = SendMessageByVal(gRtfHwnd, EM_SETEDITSTYLE, SES_ALLOWBEEPS + SES_USECRLF, SES_ALLOWBEEPS + SES_USECRLF)
To see more see http://ambracode.com/index/show/1405175 which is some copy of an old post I made at SO.

VB6: flicker free ListView with LVS_EX_DOUBLEBUFFER?

With VB6, is it possible to use LVS_EX_DOUBLEBUFFER to make the common control ListView flicker free? This property is exposed in VB.NET, but not VB6. I will be using version 6 of common controls, so in theory it should work. However I do not know how to implement it.
You could try the free VB6 replacement for the ListView from vbAccelerator. It supports LVS_EX_DOUBLEBUFFER
Alternatively use a manifest to use Common Controls 6 in your VB6. Then in the Form_Load send the LVS_EX_DOUBLEBUFFER message to the ListView. Something like this (based on a .NET sample). Warning - air code!
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, _
ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Const LVM_FIRST = &H1000
Const LVM_SETEXTENDEDLISTVIEWSTYLE = (LVM_FIRST + 54)
Const LVM_GETEXTENDEDLISTVIEWSTYLE = (LVM_FIRST + 55)
Const LVS_EX_DOUBLEBUFFER = &H10000
Const LVS_EX_BORDERSELECT = &H8000
Private Sub FormLoad()
Dim styles As Long
styles = SendMessage(listView.hwnd, _
LVM_GETEXTENDEDLISTVIEWSTYLE, 0, ByVal 0&)
styles = Style Or LVS_EX_DOUBLEBUFFER Or LVS_EX_BORDERSELECT
Call SendMessage(listView.hwnd, _
LVM_SETEXTENDEDLISTVIEWSTYLE, 0, ByVal styles)
End Sub

Resources