|
(Originally posted: 2007-10-24)
Services running on your machine are defined in the registry at:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
You can manually edit the registry to change service settings or you can use the SC windows command on the command prompt.
DESCRIPTION:
SC is a command line program used for communicating with the
NT Service Controller and services.
USAGE:
sc <server> [command] [service name] <option1> <option2>...
The option <server> has the form "\\ServerName"
Further help on commands can be obtained by typing: "sc [command]"
Commands:
query-----------Queries the status for a service, or
enumerates the status for types of services.
queryex---------Queries the extended status for a service, or
enumerates the status for types of services.
start-----------Starts a service.
pause-----------Sends a PAUSE control request to a service.
interrogate-----Sends an INTERROGATE control request to a service.
continue--------Sends a CONTINUE control request to a service.
stop------------Sends a STOP request to a service.
config----------Changes the configuration of a service (persistant).
description-----Changes the description of a service.
failure---------Changes the actions taken by a service upon failure.
qc--------------Queries the configuration information for a service.
qdescription----Queries the description for a service.
qfailure--------Queries the actions taken by a service upon failure.
delete----------Deletes a service (from the registry).
create----------Creates a service. (adds it to the registry).
control---------Sends a control to a service.
sdshow----------Displays a service's security descriptor.
sdset-----------Sets a service's security descriptor.
GetDisplayName--Gets the DisplayName for a service.
GetKeyName------Gets the ServiceKeyName for a service.
EnumDepend------Enumerates Service Dependencies.
The following commands do not require a service name:
sc <server> <command> <option>
boot------------(ok | bad) Indicates whether the last boot should
be saved as the last-known-good boot configuration
Lock------------Locks the Service Database
QueryLock-------Queries the LockStatus for the SCManager Database
EXAMPLE:
sc start MyService
|
|
|
|
|
(Originally posted: 2008-02-15)
qwinsta
Display information about Terminal Sessions.
QUERY SESSION [sessionname | username | sessionid]
[/SERVER:servername] [/MODE] [/FLOW] [/CONNECT] [/COUNTER]
sessionname Identifies the session named sessionname.
username Identifies the session with user username.
sessionid Identifies the session with ID sessionid.
/SERVER:servername The server to be queried (default is current).
/MODE Display current line settings.
/FLOW Display current flow control settings.
/CONNECT Display current connect settings.
/COUNTER Display current Terminal Services counters information.
rwinsta
Reset the session subsytem hardware and software to known initial values.
RESET SESSION {sessionname | sessionid} [/SERVER:servername] [/V]
sessionname Identifies the session with name sessionname.
sessionid Identifies the session with ID sessionid.
/SERVER:servername The server containing the session (default is current).
/V Display additional information.
. Managing Terminal Services Sessions Remotely[^]
|
|
|
|
|
(Originally posted: 2007-10-24)
Tip: When you disconnect the adaptor (or most serial port devices like a modem bluetooth IrDA device) the COM port remains allocated but does not show up in Device Manager, however you can re-use that COM port by manually selecting it if you know that it is really free. As far as I know the only way to completely free that COM port so that it is not reported as “In Use” is to plug the device in so that it shows up in device manager, then right click it and choose uninstall (or to go into the registry and manually remove the assignment).
Tools:
. Free Serial Port Monitor[^]
Reference:
. USB to serial adapter review[^]
. A diagnostic procedure[^]
|
|
|
|
|
(Originally posted: 2007-08-24)
A Solution
<style type='text/css'>
.TableContainer div {
width:900px;
padding-bottom: 20px;
overflow-x:auto;
overflow-y:hidden;
}
.locked {
position: relative;
}
</style>
This solution provides only a horizontal scroll bar. In IE, it also freezes the first column, so that the Edit buttons are always visible. The behaviour in Firfox differs.
Note: A bug in IE6.0 places Dropdown lists on top of all other elements independent of their z-index style property. There are few available hacks (using IFrame) to address the problem but they apply better in dealing with page menus rather than controls in the same div element. For more details:
. CSS Positioning[^]
. IE6, SELECT and Z-index Problem Resolution[^]
. Select Element Z-index ignored by IE6 - Workaround[^]
Horizontal And Vertical Scrolling
Ideally, the header, the footer and the first column of the grid view control can be frozen. One clever solution is to apply scrolling at two different levels - the div element containing the table and the tbody element of the table.
<style type='text/css'>
.TableContainer div{
width:800px;
padding-bottom: 20px;
overflow-x:auto;
overflow-y:hidden;
}
.locked {
position: relative;
}
.TableContainer tbody{
height:300px;
overflow-x:hidden;
overflow-y:auto;
padding-right: 20px;
}
.TableContainer tbody tr {
height: auto;
white-space: nowrap;
}
</style>
When we scroll the tbody vertically, the header and the footer of the table are not affected by design (fails not in IE6.0).
When we scroll the div element horizontally, the first column is not affected if its style position is set to relative (fails in Firefox).
. CSS position property[^]
. CSS positioning properties[^]
Note: In order to have access to the thead, tbody, and tfooter sections of the grid view table representation, they have to be programatically added after the grid is data-bound. For example, call the following funciton during the grid's OnPreRender event.
private void MakeAccessible(GridView grid)
{
if (grid.Rows.Count > 0)
{
grid.UseAccessibleHeader = true;
grid.HeaderRow.TableSection = TableRowSection.TableHeader;
grid.FooterRow.TableSection = TableRowSection.TableFooter;
if (grid.TopPagerRow != null)
{
grid.TopPagerRow.TableSection = TableRowSection.TableHeader;
}
if (grid.BottomPagerRow != null)
{
grid.BottomPagerRow.TableSection = TableRowSection.TableFooter;
}
}
}
. Make the GridView control accessible[^]
. Avoid out of order Pager rows: The table must contain row sections in order of header, body, then footer[^]
Explicit Position Calculation
The following javascript functions help setup a listener for the scrolling event and recalculate the positions of the elements on the fly. This approach allows to explicitely set the position style values and avoids the pitfalls of css behaviour interpretations by the different browsers. However, it requires more research and testing before the implementation can be successfully completed...
<script type="text/javascript">
function getElementsByClassName(oElm, strTagName, oClassNames){
var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
var arrReturnElements = new Array();
var arrRegExpClassNames = new Array();
if(typeof oClassNames == "object"){
for(var i=0; i<oClassNames.length; i++){
arrRegExpClassNames.push(new RegExp("(^|\s)" + oClassNames[i].replace(/-/g, "\-") + "(\s|$)"));
}
}
else{
arrRegExpClassNames.push(new RegExp("(^|\s)" + oClassNames.replace(/-/g, "\-") + "(\s|$)"));
}
var oElement;
var bMatchesAll;
for(var j=0; j<arrElements.length; j++){
oElement = arrElements[j];
bMatchesAll = true;
for(var k=0; k<arrRegExpClassNames.length; k++){
if(!arrRegExpClassNames[k].test(oElement.className)){
bMatchesAll = false;
break;
}
}
if(bMatchesAll){
arrReturnElements.push(oElement);
}
}
return (arrReturnElements)
}
function OnScroll(){
var cells = getElementsByClassName(document.getElementByID("div_OLMGridView"), "td", "locked");
for (var i = 0; i < cells.length; i++){
cells[i].style.left = cells[i].offsetParent.scrollLeft;
}
}
function GetScroller(){
var scroller = null;
var divs=document.getElementsByTagName('div');
for (var i = 0; i < divs.length; i++) {
if (divs[i].parentNode.getAttribute('class') == "TableContainer"){
scroller = divs[i];
break;
}
}
return (scroller);
}
function AddScrollListener(){
var scroller = GetScroller();
if (scroller != null){
if (scroller.addEventListener){
scroller.addEventListener('scroll', OnScroll, false);
} else if (scroller.attachEvent){
scroller.attachEvent('scroll', OnScroll);
}
}
}
window.onload = function(){AddScrollListener();}
</script>
In IE, exression() can be used to dynamically set style properties.
. IE Dynamic Properties[^]
For example,
<DIV STYLE="background-color: #CFCFCF; position: absolute;
left:expression(document.body.clientWidth/2-oDiv.offsetWidth/2);
top:expression(document.body.clientHeight/2-oDiv.offsetHeight/2)"></DIV>
However, its use is not recommended:
. CSS expressions in browsers other then IE[^]
. Avoid CSS expressions[^]
References
. ScrollingGrid: A cross-browser freeze-header two-way scrolling DataGrid by Ashley van Gerven[^]
. An ASP.NET DataGrid Custom Control to Freeze Header, Rows, Columns by Tittle Joseph[^]
. Real World GridView: Excel-like Frozen Headers for ASP.NET 2.0[^]
. Lock or Freeze Table Columns plus Non-Scroll Headers - Internet Explorer CSS solution[^]
. Freeze table header in Mozilla[^]
. Implementing a Fixed GridView Header in ASP.NET[^]
|
|
|
|
|
(Originally posted: 2007-09-26)
There are two Delphi functions defined in Classes that are employed in order to allow for a class to be instantiated given its class name:
. function GetClass(const ClassName: string): TPersistentClass;
. procedure RegisterClass(AClass: TPersistentClass);
The Class must be registered before GetClass can find it. Form classes and component classes that are referenced in a form declaration (instance variables) are automatically registered when the form is loaded. Other classes can be registered by calling RegisterClass or RegisterClasses.
Details:
Delphi help files
Application:
The UPOS Specification[^] is followed in an attempt to standardize the implementation of Vivonet POS Devices. Thus each POS device is derived from the TUPOSDeviceControl and TUPOSDeviceService family. A generic interface is provided to create the POS device instances (such as MSR and PinPad) based on their names (supplimented by an ini configuration file that provides the class names for the device in question):
unit uUPOSFactory;
interface
uses
uUPOSDeviceControl,
uUPOSDeviceService;
const
POSDEVICESINIFILE = 'C:\Program Files\Vivonet\iPOS\Client\PosDevices.ini';
function CreateDeviceService(DeviceName: string): TUPOSDeviceService;
function CreateDeviceControl(DeviceName: string): TUPOSDeviceControl;
implementation
uses
IniFiles,
Classes;
function GetClassName(DeviceName: string; DeviceObject: string):string;
var
iniFile: TIniFile;
begin
iniFile := TIniFile.Create(POSDEVICESINIFILE);
Result := iniFile.ReadString(DeviceName, DeviceObject, 'T' + DeviceName + DeviceObject);
iniFile.Free;
end;
function CreateDeviceService(DeviceName: string): TUPOSDeviceService;
var
DeviceClass: TPersistentClass;
begin
try
DeviceClass := GetClass(GetClassName(DeviceName, 'Service'));
Result := TUPOSDeviceService(DeviceClass.Create);
except
Result := nil;
end;
end;
function CreateDeviceControl(DeviceName: string): TUPOSDeviceControl;
var
DeviceClass: TPersistentClass;
begin
try
DeviceClass := GetClass(GetClassName(DeviceName, 'Control'));
Result := TUPOSDeviceControl(DeviceClass.Create);
except
Result := nil;
end;
end;
end.
Inspiration:
Factory Method design pattern
See Also:
Abstract Factory and Builder design patterns
|
|
|
|
|
(Originally posted: 2007-10-03)
. Set Project -> Properties -> Configuration Properties -> Linker -> Debugging -> Generate Debug Info
. Set Tools -> Options -> Debugging -> Native -> Enable RPC Debugging
. Ensure that the user account under which the application will run has enough privileges (e.g., it is part of Debugger Users). Alternatively, set the Component application identity as follows: <Component> Properties -> Identity -> System Account -> Interactive User
References:
. How to: Debug COM+ 1.0 Components[^]
. Debugging an W32 App[^]
|
|
|
|
|
|
(Originally posted: 2008-02-01)
These are the steps for setting up COM+ debugging in Windows 2000. Note that there are known issues with this and it may not work correctly, even if you follow all the steps. It is even more unlikely that it will work correctly under Windows XP.
Setting up COM+
In AdmistrativeTools -> Component Services :
. Ensure that the COM dlls registered in Component Services point to the dlls that the Delphi project will create when it compiles. Usually, this means deleting the original COM applications in Component Services, and readding the DLLs that are generated by the Delphi project compilation.
. Right click on the COM Application you are debugging (not the COM object itself), and go to Properties->Identify and ensure that 'Interactive User - the current logged on user' is selected. If you don't see the Identity tab, you may be trying to access the properties of the COM object instead of the COM application it resides in.
. Get the Application identifier for the COM object itself: Right click on the COM object and go to Properties. Under CLSID is the Application ID (a GUID). Copy this as it will be used later when setting up the Delphi Project.
Setting up the Delphi Project
In the Delphi Project you wish to debug:
. Go to Project->Options
Under the 'Linker' tab, ensure that the options 'Include TD32 debug info' and 'Include remote debug symbols' are checked.
Click OK.
. Go to Run->Parameters .
Under 'Host Application' find 'dllhost.exe' in the WINNT\system32 folder.
Under 'Parameters', paste the Application identifier you got from earlier (see Setting up COM+). Entering in '/ProcessID:{GUID}', where GUID is the Application identifier, may work better.
Click OK.
The application should now be set up to debug. Set the breakpoints you want the debugger to stop at, and click Run. If all goes well, the project will be shown in run mode and will wait for the break point to hit.
Troubleshooting
If your break points are not being hit:
. It is recommended that dllhost.exe is copied to the directory where the COM+ dll file is and it is referred to in Delphi 'Host Application' step above. This is a required step on a Windows XP machine.
. You may need to set the Include remote debug symbols option under Project | Options | Linker. Make sure to shutdown the COM+ application that contains the DLL first. This can be done fom the Component Services Admin utility.
. Change the COM+ application settings to Activation -> Library and use Shift+F7 to step into the com+ code
. The pathfilename of the dll containing the COM is not in 8.3 format. There are 2 solutions:
1: Put de DLL in a directory in 8.3 format like C:\Test\MyCom.dll and NOT C:\My Test\My Com.dll
2: Put your DLL anywhere, register it, search the registration key with RegEdit and change the pathfilename in the registry by the long pathfilename format like C:\My Test\My Com.dll
Resources
. CodeGear from Borland[^]
. Debugging COM+ services written in Delphi 7 (D7)[^]
. Why can't I get breakpoints to work when debugging a COM+ or MTS app in Delphi?[^]
. On Windows XP, it is very difficult to set breakpoints in a COM, Delphi do not stops[^]
|
|
|
|
|
(Originally posted: 2007-10-11)
Check the EventViewer Application log:
. Go to Start -> Control Panel -> Administrative Tools -> Event Viewer
. Look for Error with Source: COM+ and Event ID: 4786.
|
|
|
|
|
(originally posted: 2007-10-12)
There are many representations of text in C++. Usage and conversion should be done with great care...
. (Visual C++) How to: Convert Between Various String Types[^]
This article only touches on the issue of CURRENCY data type.
CURRENCY is implemented as an 8-byte two's-complement integer value scaled by 10,000. This gives a fixed-point number with 15 digits to the left of the decimal point and 4 digits to the right. The CURRENCY data type is very useful for calculations involving money, or for any fixed-point calculations where accuracy is important.
Here is the code used in Mercury.cpp of VivoClientApi.dll that converts CURRENCY to text and vice versa for the purposes of the Mercury project (text is used loosely )
CURRENCY2Text:
CURRENCY Currency_Amount;
CString Currency_Text = "";
Currency_Text.Format("%.2f", (float)(Currency_Amount.int64) / 10000);
Text2CURRENCY (reading from an XML doc):
CURRENCY Currency_Amount;
COleCurrency COleCurr_Amount;
MSXML::IXMLDOMNodePtr pNode;
pNode = pDOMDoc->selectSingleNode("//Amount/Authorize");
if(pNode)
{
COleCurr_Amount.ParseCurrency(W2T(pNode->Gettext()));
Currency_Amount = COleCurr_Amount.m_cur;
}
See Also:
. MFC Simple Data Types[^]
. MFC COleCurrency[^]
. ATL CComCurrency[^]
. Component Automation: CURRENCY[^]
|
|
|
|
|
(Originally posted: 2007-09-20)
The call to Application.ProcessMessages requires the inclusion of Forms unit.
If the size of the dll is of a concern, consider replacing the call with:
while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
For more details: http://www.delphipages.com/forum/showthread.php?t=181620[^]
Here is the Application.ProcessMessage() extracted from the Forms.pas:
function TApplication.ProcessMessage(var Msg: TMsg): Boolean;
var
Handled: Boolean;
begin
Result := False;
if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then
begin
Result := True;
if Msg.Message <> WM_QUIT then
begin
Handled := False;
if Assigned(FOnMessage) then FOnMessage(Msg, Handled);
if not IsHintMsg(Msg) and not Handled and not IsMDIMsg(Msg) and
not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end
else
FTerminate := True;
end;
end;
Note: This function requires Windows.pas and Messages.pas.
|
|
|
|
|