Disable column in MSHFlexGrid in VB6.0 - vb6

How do I disable particular columns in MSHFlexgrid in VB6.0? I don't want my user to edit the values in a particular column.

I don't think the MSHFlexGrid control allows users to edit its data in the first place. Therefore, in effect, all columns are disabled. Job done :)
In fact, you have to add custom code to enable updating e.g. add an appropriate control (textbox, combo, date picker, etc) that does allow editing, hide it at design time, then at run time detect which grid cell should have focus, move and size the control to fit the cell then make it visible then handle events to validate the input then write the contents back to the recordset...
...or you could purchase a third party control that does all this out of the box. The MSHFlexGrid that ships with VB6 is essentially a cut-down version of VSFlexGrid Pro, which I've used and thought was quite good. It has a different way of handling hierarchical data by creating groups (rather than bands) which is superior, IMO. The best thing that can be said about the MSHFlexGrid is that it is easy to bind to a hierarchical ADO recordset to simply display the results but not good if you want to do nice formatting or make the grid editable. The VSFlexGrid Pro, if you can afford it, has more power e.g. you can create data source classes to handle binding to custom data structures (ships with VB6 examples of this including ADO recordset binding) which would be invaluable IMO if you intend to make your hierarchical grid editable.

'A Shortcut way is here... NOT in a proper way. But you can try
'if you need to lock the first 3 columns please use this code:
msf2=name of MSFlexGrid
Private Sub msF2_EnterCell()
With msF2
If msF2.Col = 0 Or msF2.Col = 1 Or msF2.Col = 2 Then
msF2.Col = 3
End If
End With
End Sub

Related

IAccessible deisgn questions: child objects, thread safety, and header rows/comctl32.dll header controls, and a few other questions on top of that

So before I continue developing my accessible table I read this, on exposing data tables and the general MSAA documentation and I want to clear up a few things before I actually go ahead and write out this implementation, just so I can get everything just right.
For the record, this table is strictly owner-data and is row-based, where a given row can be selected, and a single cell within this row can be focused. Otherwise it behaves similarly to a listview control, but is not one, so I'm not going to try to take advantage of its accessibility features. In particular, any column can contain text, images, or checkboxes (and I might add more features); there might be background colors and text editability in the future as well. All cells in a given column have one of these types. The type will not change during runtime.
I am choosing to use MSAA because I still need Windows XP support, and I would rather not require developers and end users to have both SP3 and the .net framework together, which UI Automation seems to require (and even if the SP3 part is wrong, the "is not standalone/does not come out of the box with the OS" part still makes me uneasy about implementing that).
Is it process-safe/thread-safe to call my internal control functions within the accessible object method implementations, or should I use WM_USER messages to make sure everything happens all on one thread of one process? (In addition, would my error handling/debugging traps be run in the client or in the server in either case?)
From what I can gather, I need to build a three-level IAccessible hierarchy: the table itself on top, followed by each row, followed by each cell in the row. However, the various IAccessible methods that take a child object only take a VT_I4 VARIANT to specify the child. Does this mean I'm going to have to create an IAccessible for each row as well, or for each cell as well, or something else? Should I have a standard accessible object for each of these? Can they share? And what about NotifyWinEvent(); how would I indicate that a given cell has changed? Or should I say the whole row has changed...?
If the answer to question 2 is "yes", I'm going to wind up with a lot of IAccessible objects that need to be notified when the table control is destroyed. If the answer to question 1 is "it is not thread-safe", then is it safe to hold a lock in my IAccessible methods whenever I access my table control and have that hold the lock when it's time to invalidate all those IAccessibles? Or should I investigate some other approach? I see talk on MSDN of "proxy objects" but I'm not really following how that would help... especially if I need to make lots of IAccessibles.
From what I can gather I need to return (number of rows) + 1 rows in my table's get_accChildCount() method, with the first row being full of column header cells. But I'm not using a custom header control; I'm using the standard comctl32.dll header control. Should I hide that control and construct my column headers according to the Exposing Data Tables document or should I relegate the first row to the header control? I don't see a way to do both... (I do not have row headers, so will not be implementing that.) Columns can be user-resized, but may be automatically sized to fit until the user first does so (maybe).
Is it safe to relegate IDispatch methods to the window handle's standard accessible object? Even in the case of the row and cell IAccessibles? Or will the standard accessible object's IDispatch not call my IAccessible methods?
What should accDoDefaultAction() do for a checkbox cell, toggle the checkbox state? And for an editable text cell, should it enter editing mode?
Thanks. (Hoping none of this sounds dumb...)
UPDATE 6 January 2015
I changed the wording of some of the paragraphs above and have one more question:
How do I correctly check for errors from LresultFromObject(), by casting to an HRESULT and checking that, or by comparing a signed version of the LRESULT value and seeing if it's less than zero, or something else?

Excel VBA - Is there a TextChanging / TextChanged or a similar event? Or how to move a selection without using Enter?

I have recently been asked if I could make a macro in Excel VBA that will allow a user to type in two numbers and have it automatically drop to the next row. The purpose of this is so they can type in grades for a test two numbers at a time without pressing enter since they aren't great at typing.
When I first heard this he mentioned it was Visual Basic, so I figured I'd just use a TextChanging or TextChanged event in the cell range and have it work off that. However, I haven't been able to find any such event or anything resembling it in the documentation thus far. The first thing that I came across was Workbook_Change, but that only changes after you press enter which is useless to me. Someone else mentioned there is such an event, but couldn't name it directly and I haven't been able to find what they were talking about.
If anyone has any information on if such an event exists or is possible I'd love to know.
The Excel version is 2007 as far as I'm aware.
This, in my opinion, requires a non-programming solution. I absolutely sympathize - it is tough to watch people get old - but you have to draw the line somewhere - for their sake and yours. The enter key is the most basic part of a computer. You could probably write a macro that would automatically hit enter on every even(or odd depending) keystroke in excel - but you're going to run into other problems like not being able to use delete normally. And what if you do want to put a string of text in a cell(like the student's name)? Perhaps it is time to find a non-programming solution. By that I mean someone should have a candid conversation with him about how he wants to solve the problem. Personally, I would offer to type the numbers in for him, as I am accustomed to the number pad - but it is probably better to be more direct and start to discuss retirement.
See this discussion about the limitations of cell edit mode in excel:
http://www.mrexcel.com/forum/excel-questions/524860-call-macro-every-keystroke.html
If you're really heart-set on a programming solution, I would recommend some kind of keystroke logging add-in.
Good Luck.
You could use the Worksheet_SelectionChange event. It is triggered without enter, but it would be triggered a lot.
You could however also create a special user-form for typing in the data, but this might be more work than necessary.
The main problem with using my suggested event is, you will need it as trigger and trigger it yourself, when selecting the next row, so disable event handling before changing the selection.
Edit:
This is a quick solution (paste this into the vba-code of the desired worksheet):
Private Const clngColumnRightToLastGrade = 5
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Target.Column = clngColumnRightToLastGrade Then
Application.EnableEvents = False
'offset selection, one row down, two cols to left
Target.Offset(1, -2).Select
Application.EnableEvents = True
End If
End Sub
This will set you one row down and to column C, everytime your selection changes to column E (=5).
You don't have to use a constant of course, you could specify the column to sense in the workbook, so your user might modify it easier by himself.
To make this as an optional feature, you could extend it to autogenerated code. What I have in mind is like a Ribbon-Button, which opens a setupForm to configure, and a Ribbon-Button to activate the configuration, which would place this code in the configured sheet. But this might be a bit over the top.
In Excel 2003, (may be different in Excel2007 ?!) the WorkSheet_Change event is triggered every time the value of a cell is changed wether it is by pressing enter, delete, selecting an other cell after modifying a cell or even when a vba script changes the value of a cell.
I would do something like that:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim RefRange As Range
Set RefRange = Intersect(ActiveSheet.Columns("??????????"), ActiveSheet.UsedRange)
If Not Intersect(Target, RefRange) Is Nothing Then
Target.Offset(0, 1).EntireColumn.Range("A1").Select
'Target.Offset(0, 1).EntireColumn.Range("A65536").End(xlUp).Offset(1,0).Select
End If
End Sub

Ajax-like appearing/disappearing elements in Access 2010 web database project

I'm trying to have a feature to allow users choose two different methods of cost calculation: either they can enter a yearly cost breakdown on a datasheet (2010: $10,000, 2011: $12,000, etc) or they can enter a flat yearly cost multiplied by the number of years they select.
If I were developing another kind of web application, I'd have radio buttons to select two different options. One option would display the datasheet, and the other option would display two text fields to enter values into. However, I understand that you can't have radio buttons in Access 2010 web databases. Also, is it possible to make elements appear and disappear based on a combo box selection?
If not, perhaps I could have two different combo box options: "enter yearly cost breakdown"
or "enter flat yearly cost," which open the correct respective forms as pop-ups.
So, 1) can I have Ajax-like appearing and disappearing elements as triggered by a combo box (or ideally, radio buttons), and 2) if not, can anyone think of another clever way of doing it?
Sure, you get a nice effect by using a tab control. You can place controls and even a sub form on that tab control.
So, you build a screen like this:
Then, simple set the visible property of the second tab = No. This will hide the tab (don't change this until you built the page since it will hide it! (use property sheet to hide/un-hide during development).
Now, add some code to the after update event of the list box. Like this:
In the above, I have named the tabs PYear and PFlat.
The result is this (this is a animated gif I inserted):
Of course, you really probably could just dump the whole "list box" selection, and use a screen like this with the tabs (tabs are good UI, and users tend to grasp them quick):
So, you can hide a "set" of controls, and it really far less work and hassle then writing a bunch of JaveScript anyway. As noted, the "set" of controls you drop into each of the tabs can be sub forms, and also that of continues forms. So, the "hiding" as a set does work well in this case. I did have some format issues and found that I had to "start out" with the 2nd tab dispaled first (the first one being hidden). As noted, the listbox selecting is nice, but one could likly just go with using tabs in the first place.

Is there a SetText message for the Win32 ListBox control?

This is easy in .NET (not my question) but I'm trying to figure out if it is possible to simply change the text of a string in a Win32 list box control given an index.
There is a GetText function that takes an item index but nothing to change the text of an existing item/string. My workaround will be to remove it and add it back in the box (which is also a weird prospect since there is no single command to add a string + item data -- these must be done carefully by inserting the string and then setting the item data on the index of the inserted string, which is tricky (not possible?) with sorting active).
Yes, the lack of a LB_SETITEMTEXT message is a bit weird.
You should put your Delete+Insert+SetData calls between calls to WM_SETREDRAW...
At the risk of being off topic...
I tend to use the ListView control all of the time. You'll want it in report view to mimic a listbox, and, as a plus, it supports multiple columns.
Oh.. and it has a LVM_SETITEM Message :)
http://msdn.microsoft.com/en-us/library/bb761186(v=VS.85).aspx
Although this question is old, but I think this documentation presented by Microsoft will be able to answer anyone questions based on this one.
So according to Microsoft documentation which you can find here
Changes the text of a list-view item or subitem. You can use this
macro or send the LVM_SETITEMTEXT message explicitly.
void ListView_SetItemText(
hwndLV,
i,
iSubItem_,
pszText_
);
And it also presents other macros for managing the list box. You can build a wrapper around this macros to simplify handling list view controls, etc.

Is there a way to nest an Excel spreadsheet within another Excel spreadsheet?

I am not entirely sure if this is the place to ask this, but this is the only think I could think of. I want to know if I could have a spreadsheet, say 10 cells wide. I would like the first 5 cells to be static, and the second 5 to be A/B based on, I guess a drop down? Not sure if this is possible, thanks for the input.
Both are possible.
In regards to the static question, you want to look at Excel's ability to Split the worksheet and then Freeze sections. With Excel 2007 you can find this within the View ribbon and Window group. (I am not sure of the exact menu terminology.)
For a cell to act as a Dropdown, you want to look at Data Validation. This option (with Excel 2007) is found under the Data ribbon within the Data Tools section. This allows you to set a given cell to dates, times, whole numbers, and lists. With the list you set the source to a range elsewhere in the workbook and the cell will render as a dropdown.
Hope this helps.

Resources