I have a menu-like MFC control which hosts a lot of menu-entries (with command IDs). The number of menu-entries as well as the structure changes dynamically during runtime. That means that I have to create controls and assign new IDs dynamically from time to time.
What I did so far is to reserve a large static range of IDs and assign them sequentially. Even though the range is pretty large I'm afraid I will end up at the point where there are no IDs left. I cannot start over at the beginning either because I do not know which of the previously assigned IDs have been released.
My first thought was to find the largest command ID in the current resource handle and start from there. But I don't know how to accomplish that.
Or is there a better way to manage this? I think I might not be the first person with this kind of problem.
Hmm. It is not very possible to run out of IDs. You can start from WM_USER and increment the ID each time with 1. But if you really think that you can run out of IDs then you can use a stack or list keeping the already used IDs and reuse them the next time when you need ID. When you finish processing the message add the ID into the stack with push(ID) method (you can pass the ID with LPARAM of the ON_MESSAGE macro in MFC). Then when you need a new ID first check if the ID stack is empty, if not take the top ID with pop(). Only if the IDs stack is empty use the last available in the range ID.
Related
I aim to use the native storage plugin to store a potentially large list of objects in Ionic 3. I want to be able to then display the list in an Ionic infinite scrolling list. I presume that if I save the entire list to storage as a single object, with a single key, it will take quite some time to retrieve it, and the list page will remain empty for some time while the list is read asynchronously from storage.
Should I be saving each item in the list with an individual key, such as "key.1", "key.2", "key.3" etc, and then retrieving a "pageful" of items at a time, supported by the infinite scrolling list? The nuisance part of this is that when I want to add a new item to the list, I have to know what key number I'm up to, so I can generate the next key name.
What's the best practice for this scenario? Is there a better way to load a large list from memory asynchronously so that it can be displayed to the user as soon as possible?
I ended up storing my items in a table in a SQLite database, as I wanted to avoid the size limitations that local storage can impose. I use a query like SELECT * FROM submissions LIMIT ? OFFSET ? to fetch a pageful of items at a time from the doInfinite function of an Ionic infinite scroller, keeping track of what page I'm up to and passing that into the OFFSET parameter. The LIMIT argument is the number of rows to fetch for a page, e.g. 10.
I am having a problem in QTP with selection of a web list box and I have exhausted what I know to do to resolve it. I am hoping someone can help.
There are 5 controls in a container, 2 webedit controls and 3 weblist controls. Together, they allow entry of accounts associated with a customer, and there can be 16 accounts for any customer. There are only ever five controls active at any time, whether editing or entering information for an account. When the information for an account is entered and accepted, it changes to a read-only table row and a new set of controls appears below it for entry of the next account.
The information entered in these controls is the account number, type, description, designation, and status. The status value is contingent on the designation, and the items in the list change dynamically depending on what the user specifies for the designation. The status list is not enabled until the designation is specified.
After some experimenting with timing, I was able to get past an issue where the status list for the first account was seen by QTP as disabled even though it was clearly enabled. I was then able to advance to entry of the second account.
I change the designation on the second account and try to select an appropriate item (specified in a data table) in the status list. My specification from the data table is never found. I figured it was a problem with verbiage differences and also that I should probably anticipate that and address it now, so I wrote a function to accept three parameters, the list and up to two search items. My function searches the listbox passed to it and looks for a match (full or partial) on the search items it receives. Here is where I encountered a significant problem.
The list of the control my function received was from the previous iteration of the test, corresponding to the designation of that account. This is why my function was not finding the selection item. The list on the screen shows the appropriate items, which suggests that I am looking at the wrong object. I also get the ‘object is disabled’ message when I put my data table value directly into the list with the select statement.
The active controls are displayed below the readonly presentation of the previously entered accounts. I am very new to QTP, but I also read documentation. My only theory at this point is that ATP is not passing the right list to my function… that perhaps that how it was learned included the position, which will change each time. However, the spy identifies the screen control as the same item I processed for the preceding account, which makes my theory suspect. In addition, the other four controls, which are not dynamically changing, do not present the same problem. I can put the information in them consistently.
I apologize for the length of this question, but I wanted to be as thorough and clear as possible. Can anyone help me get past this obstacle.
There are many possiblities why it is exposing this behaviour, so let's start with something simple:
Did you try a myWebList.Refresh call before you do something with the listbox? Refresh re-identifies the object.
Have you put a break point (red dot) inside the custom function. Just see what is happening there. With the debug viewer you can enter a realtime command in the scope of that function like msgbox myWebList.exist(0) or myWebList.Highlight
Can you see how the disabled property is propagated to the webpage? If you can 'Object Spy' it as TO property, you can add it in the GUI Map description.
A more sophisticated aproach is to create a Description with the weblist properties. If you can read the disabled property as an RO property from the 'Object Spy', you can use it as an identifier like "attribute/customDisabledProperty:=false".
If you cannot correctly read the disabled property, you can create a description object and do a count on the amount of items that match that description on that page with numberOfLists = Browser("my browser").Page("my page").ChildObjects(myDescription).Count and get the last list with Set lastList = Browser("my browser").Page("my page").ChildObjects(myDescription)(numberOfLists-1)
Keep us informed. Depending on how this works out, we can work into a direction for a solution.
I figured this out early this morning. There are 4 different list boxes used, each made visible or enabled dependent on the selection of the previous list. This is why the spy found the one listed when I was using it and also why the items in the list were not appropriate to what I had selected and also why it appeared disabled to QTP but enabled to me.
I was selecting the same designation when trying to spy it. It was intuitive that the controls were all the same. I am also a windows programmer and I would have populated the same list each time with the appropriate list items, and I presumed that was what the web developer was doing. It was not and it took some time to figure that out. Now that I figured it out, everything is working fine, and I came back to report that. This was a significant, time-intensive lesson.
Thank you very much for your input. It is still useful because I am very new to QTP and every thing I learn is of value.
I'm looking to create a simple web service that when polled returns a unique id. The ID has to be human readable (i.e. not a guid, probably in the form 000023) and is simply incremented by 1 each time its called.
Now I need to consider that it may be called by two different applications at the same time and I don't want it to return the same number to each application.
Is there another option than using a database to store the current number?
Surely this has been done before, can anyone point me at some source code if it is.
Thanks,
Neil
Use a critical section piece of code to control flow one at a time through a section of code. You can do this using the lock statement or by being slightly more hardcore and using a mutex directly. Doing this will ensure that you return a different number to each caller.
As for storing it, using a database is overkill for returning an auto incrementing number - although SQLServer and Oracle (and most likely others but i can't speak for them) both provide an auto incrementing keys feature, so you could have the webservice called, generate a new entry in the database table, return the key, and the caller can use that number as a key back to that record (if you are saving more data later after the initial call). This way you also let the database worry about the generation of unique numbers, you don't have to worry about the details of it - although this is not a good option if you don't already have a database.
The other option is to store it in a local file, although that would be expensive to read the file, increment the number, and write it back out, all within a critical section.
you can use a file.
Pseudocode:
if (!locked('counter.txt'))
counter = read('counter.txt')
else
wait
startAgain
lock('counter.txt')
counter++
print counter
write('counter.txt', counter)
unlock('counter.txt)
I am currently developing an application for Azure Table Storage. In that application I have table which will have relatively few inserts (a couple of thousand/day) and the primary key of these entities will be used in another table, which will have billions of rows.
Therefore I am looking for a way to use an auto-incremented integer, instead of GUID, as primary key in the small table (since it will save lots of storage and scalability of the inserts is not really an issue).
There've been some discussions on the topic, e.g. on http://social.msdn.microsoft.com/Forums/en/windowsazure/thread/6b7d1ece-301b-44f1-85ab-eeb274349797.
However, since concurrency problems can be really hard to debug and spot, I am a bit uncomfortable with implementing this on own. My question is therefore if there is a well tested impelemntation of this?
For everyone who will find it in search, there is a better solution. Minimal time for table lock is 15 seconds - that's awful. Do not use it if you want to create a truly scalable solution. Use Etag!
Create one entity in table for ID (you can even name it as ID or whatever).
1) Read it.
2) Increment.
3) InsertOrUpdate WITH ETag specified (from the read query).
if last operation (InsertOrUpdate) succeeds, then you have a new, unique, auto-incremented ID. If it fails (exception with HttpStatusCode == 412), it means that some other client changed it. So, repeat again 1,2 and 3.
The usual time for Read+InsertOrUpdate is less than 200ms. My test utility with source on github.
See UniqueIdGenerator class by Josh Twist.
I haven't implemented this yet but am working on it ...
You could seed a queue with your next ids to use, then just pick them off the queue when you need them.
You need to keep a table to contain the value of the biggest number added to the queue. If you know you won't be using a ton of the integers, you could have a worker every so often wake up and make sure the queue still has integers in it. You could also have a used int queue the worker could check to keep an eye on usage.
You could also hook that worker up so if the queue was empty when your code needed an id (by chance) it could interupt the worker's nap to create more keys asap.
If that call failed you would need a way to (tell the worker you are going to do the work for them (lock), then do the workers work of getting the next id and unlock)
lock
get the last key created from the table
increment and save
unlock
then use the new value.
The solution I found that prevents duplicate ids and lets you autoincrement it is to
lock (lease) a blob and let that act as a logical gate.
Then read the value.
Write the incremented value
Release the lease
Use the value in your app/table
Then if your worker role were to crash during that process, then you would only have a missing ID in your store. IMHO that is better than duplicates.
Here is a code sample and more information on this approach from Steve Marx
If you really need to avoid guids, have you considered using something based on date/time and then leveraging partition keys to minimize the concurrency risk.
Your partition key could be by user, year, month, day, hour, etc and the row key could be the rest of the datetime at a small enough timespan to control concurrency.
Of course you have to ask yourself, at the price of date in Azure, if avoiding a Guid is really worth all of this extra effort (assuming a Guid will just work).
I am using a List Control to display a representation of elements within a vector. When the list is clicked on another control shows information about that element. The index of the element is currently determined by its index in the control, however if I wish to sort or filter the results this will no longer work.
I have been told that I could use a virtual list control, but the MSDN is not very friendly, can someone run me through how I could use a virtual list control for this?
Frankly - tying data (the position in your data vector) to the presentation of the data in the list control (the position in the list ctrl) is something I would stay away from.
In MFC each control has a "Data" DWORD member variable - when coding in MFC I Always called "SetItemData" for each item added and passed in a pointer that the relevant row referred to e.g.
YourListCtrl.SetItemData((DWORDPTR)&YourData);
Then when the ListCtrl item is selected, you just call
DataTypeYouWant* pData = (DataTypeYouWant*)(YourListCtrl.GetItemData(indexofselecteditem));
Or somesuch thing.
Alternatively - if you don't want to use pointers - hold the index of the item in your original vector in the itemdata for your row (just pass it into the above fns).
To use a virtual list control, set the LVS_OWNERDATA style. You then need to handle the LVN_GETDISPINFO notification message (which is sent via WM_NOTIFY).
If you do this, you are entirely responsible for the data, including the order in which it is shown. Therefore it is up to you to handle sorting and so forth.
By far the easiest way is just to use the item data to set/get an ID that can be used to retrieve the original data, whether that's a vector index or a pointer to the data, or even a key into an associative container.
It really depends on the performance you require.
I have personally seen MAJOR increases in performance for lists holding massive amount of data. However it is much more work to implement, thus for simple uses with not so many data I recommend staying away from it.
Basically, what happens with virtual list controls is that you have your data somewhere in some data structure of your own. Since the list view shows only a small subset of the whole data, it queries you for the content to display when ever something happens (redraw necessary, scroll up or down, change the sorting, etc.).
I don't have handy examples for you. But you can look on codeguru, I am quite sure there are very good examples to start from.
The purpose of virtual list controls is totally different: You should use it for performance reason when you have A LOT of items in your list (I'd say 2500+).
In your case, all you need is to store the vector index in the list item data as NotJarvis explains.