(c) 2002 Visual Studio Magazine 
Fawcette Technical Publications

Issue: November 2002
Section: Q&A
Author: Karl E. Peterson and Juval Lowy

VB5, VB6	Adjust Your Response
Listing 1	Applications might need to be responsive to the user immediately regardless of system load, or they might want to only execute when the system isn't too busy. Adjusting the overall priority the system assigns your application is as simple as passing a known handle to the routines in this code, along with the desired priority setting. Be sure to read the warnings in the SDK docs about "real-time" processes, and their ability to destabilize the system, before using your desired setting. You should carefully consider even "high" priority usage, as such a setting can consume the CPU fully.

Option Explicit

' Win32 API declarations
Private Declare Function _
	GetWindowThreadProcessId Lib "user32" ( _
	ByVal hWnd As Long, lpdwProcessId As Long) _
	As Long
Private Declare Function OpenProcess Lib _
	"kernel32" (ByVal dwDesiredAccess As Long, _
	ByVal bInheritHandle As Long, _
	ByVal dwProcessID As Long) As Long
Private Declare Function SetPriorityClass Lib _
	"kernel32" (ByVal hProcess As Long, _
	ByVal dwPriorityClass As Long) As Long
Private Declare Function GetPriorityClass Lib _
	"kernel32" (ByVal hProcess As Long) As Long
Private Declare Function CloseHandle Lib _
	"kernel32" (ByVal hObject As Long) As Long

' Used by the OpenProcess API call
Private Const PROCESS_QUERY_INFORMATION _
	As Long = &H400
Private Const PROCESS_SET_INFORMATION _
	As Long = &H200

' Used by SetPriorityClass
Private Const NORMAL_PRIORITY_CLASS = &H20
Private Const IDLE_PRIORITY_CLASS = &H40
Private Const HIGH_PRIORITY_CLASS = &H80
Private Const REALTIME_PRIORITY_CLASS = &H100

Public Enum ProcessPriorities
	ppIdle = IDLE_PRIORITY_CLASS
	ppNormal = NORMAL_PRIORITY_CLASS
	ppHigh = HIGH_PRIORITY_CLASS
	ppRealtime = REALTIME_PRIORITY_CLASS
End Enum

Public Function GetProcessPriority(Optional _
	ByVal ProcessID As Long, Optional ByVal hWnd _
	As Long) As Long
	Dim hProc As Long
	Const fdwAccess As Long = _
		PROCESS_QUERY_INFORMATION

	' If not passed a PID, then find value from 
	' hWnd.
	If ProcessID = 0 Then
		Call GetWindowThreadProcessId(hWnd, _
			ProcessID)
	End If

	' Need to open process with simple query 
	' rights, get the current setting, and close 
	' handle.
	hProc = OpenProcess(fdwAccess, 0&, ProcessID)
	GetProcessPriority = GetPriorityClass(hProc)
	Call CloseHandle(hProc)
End Function

Public Function SetProcessPriority(Optional _
	ByVal ProcessID As Long, Optional ByVal hWnd _
	As Long, Optional ByVal Priority As _
	ProcessPriorities = NORMAL_PRIORITY_CLASS) _
	As Long
	Dim hProc As Long
	Const fdwAccess1 As Long = _
		PROCESS_QUERY_INFORMATION Or _
		PROCESS_SET_INFORMATION
	Const fdwAccess2 As Long = _
		PROCESS_QUERY_INFORMATION

	' If not passed a PID, then find value from 
	' hWnd.
	If ProcessID = 0 Then
		Call GetWindowThreadProcessId(hWnd, _
			ProcessID)
	End If

	' Need to open process with setinfo rights.
	hProc = OpenProcess(fdwAccess1, 0&, ProcessID)
	If hProc Then
		' Attempt to set new priority.
		Call SetPriorityClass(hProc, Priority)
	Else
		' Weren't allowed to setinfo, so just open 
		' to enable return of current priority 
		' setting.
		hProc = OpenProcess(fdwAccess2, 0&, _
			ProcessID)
	End If

	' Get current/new setting.
	SetProcessPriority = GetPriorityClass(hProc)
	' Clean up.
	Call CloseHandle(hProc)
End Function

C#	Set Up the Error Provider
Listing 2	Once the application logic decides to provide an error alert to the user, you need to tell the Error Provider which control to display the error icon and the error message. The error message is displayed as a tool tip.

void OnOK(object sender,EventArgs e)
{
	if(m_FirstNameTextBox.Text == "")
	{
		m_ErrorProvider.SetError(m_FirstNameTextBox,
		"Please enter first name");
	}
	else
	{
		m_ErrorProvider.SetError(m_FirstNameTextBox,""
		);
	}
	if(m_LastNameTextBox.Text == "")
	{
		m_ErrorProvider.SetError(m_LastNameTextBox,
			"Please enter last name");
	}
	else
	{
		m_ErrorProvider.SetError(m_LastNameTextBox,"");
	}

}

