« first day (1473 days earlier)      last day (1707 days later) » 
00:00 - 18:0018:00 - 00:00

12:00 AM
RELOAD!
[rubberduck-vba/Rubberduck] 9 commits. 1 opened issue. 3 closed issues. 12 issue comments. 629 additions. 113 deletions.
 
 
6 hours later…
TIL, the Common VBA registry key is for common settings, but the SDK allows a VBE developer to specify a host-specific registry key. That is, a host could have its own unique VBE settings, or just use the Common ones.
 
 
3 hours later…
9:24 AM
> There are a number of issues with Delaration.cs. This issue serves as a placeholder to discuss and revise this core class and its associated classes and enums.

Declarations are central to many features of RD, namely the resolver and inspections, so changes to these files will entail many changes in other parts of RD. Let's think very carefully about how we revise these critical files.

### Accessibility.cs
The current enum has 6 members, despite VBA only having 3 levels of accessibility
 
9:58 AM
> I agree except for two points:
1. I do not think we need a property to state whether that global has been used to declare the accessibility. That is only interesting for an inspection, which can simply look at the `context` or be implemented as parse tree inspection.
2. I think we should have an `IsStatic` property instead of `DeclarationIsExplicitlyStatic`.
> Possibly related: #4045
> I agree except for two points:
1. I do not think we need a property to state whether that global has been used to declare the accessibility. That is only interesting for an inspection, which can simply look at the `context` or be implemented as parse tree inspection.
2. I think we should have an `IsStatic` property instead of `DeclarationIsExplicitlyStatic`. Whether it is explicitly static can be determined from the `context`.

In addition to the changes mentioned already, I think we shou
 
Hey all... hope you're well :) ! I have a question:
Is there anything wrong with using the default instance (?) of an enum?
Private Enum Colours
    Blue = vbBlue
    Red = vbRed
    Green = vbGreen
End Enum

Private Sub Something()
    MsgBox Colours.Blue
End Sub
(obviously not a meaningful example but illustrates the point)
Rather than creating a variable As Colours
 
10:25 AM
> Not an issue, but a request: I can click on one proc at a time and see its LOC and complexity. Is there a report for the whole project so I can rank procs for attention? 2.2.0.3398-pre
> I get less space for the code in the left pane than for the brief metrics in the right pane. I'd like to resize them.
 
10:59 AM
@CallumDA enums are just bunched-up constants, they're made for this. They're especially useful when you need to pass one of a limited number of meaningful numerical values to a method as a parameter: it's easier for the calling code to know what values are ok to use. MsgBox is a good example with its vbOkCancel and vbExclamation arguments =)
 
> For example, " parameter is passed byval but assigned a value", in the Location column I just see projectname.modulename so I get several of the same warning in the same location. It might be more explicit to show the procedure name as well.
> I can expand or collapse the general type eg Code Quality Issues. Would it be possible to add a subgroup button so that I can temporarily put away eg "parameter ... is implicitly passed by reference", work on the other ones, and then come back to the ones I grouped?
> Lots of these ... RD isn't recognising VBA functions and the vb* constants, etc.
Probably just a new bug in 2.2.0.3398
 
11:18 AM
@MathieuGuindon, thanks - that's exactly what I though
thought*
However, I often use them for keeping track of the status of something - at which point I do need to create a variable to hold the current status
 
@Duga Don't the inspection results show the location?
 
I mean, the actual location in the module as LxCy.
 
11:38 AM
@M.Doerner they do (required for navigation)... but the 'location' column has always been more or less useless. It's using the QMN (module) rather than QMN (member), ..member was tried at one point but felt wrong half the time, e.g. VBProject.VBProject.VBProject at project level, VBProject.ModuleName.ModuleName at module level,...we need some layer of abstraction between the QMN and what's getting displayed I think.
 
Does the inspection results have a QualifiedSelection?
 
12:05 PM
They should, yeah
 
12:50 PM
Regarding the declaration type hierarchy update and the type library integration, I am planning to implement both if nobody wants to do it before I have time for it. However, I will be busy until October and not able to actually do it until then.
 
♫ 199 releases on GitHub, 199 releases. Build one up, compile it clean. 200 releases on GitHub! ♫
checks calendar. Nope, not as busy as @M.Doerner!
 
Well, I am getting married this year.
14
 
Congrats, @M.Doerner
Pretty the pretty missus will prefer that you make her the primary focus over the duck. ;-)
 
> Language opportunities
"Fix all occurences" --> occurrences
 
Congrats indeed! Notes the beginning of a trend.
 
@FreeMan new slogan Single, knows C# and looking to be married soon? Contribute to Rubberduck project!
 
@this Hasn't worked for me yet.
But maybe Vogel could propose.
 
@this Indeed! noted that Thunderframe went offline moments after I posted that comment. Not sure about Thurderframe's marital status...
@Hosch250 patience, young grasshopper. All good things take time!
 
It needs to happen before winter, or it won't happen :P
(Joke about winter killing grasshoppers.)
 
ATTENTION LADIES!!! @Hosch250 will be totally out of "I do" by early December. Get yours now before they're gone forever!
there went the joke...
 
1:08 PM
LOL.
 
1:24 PM
> ReDim Result(StringLen) As String
gets me several warnings:
Variable 'Result' is used but not assigned
Local variable 'Result' is not declared.

This gives no warnings:

Dim Result() As String
ReDim Result(StringLen)
 
@M.Doerner congrats!!
 
Just checking --- I seem to recall someone saying this is an anti-pattern. Is it so?
void foo()
{
  dothis();
  dothat();
  doThisToo();
}
e.g. requiring that a set of methods be called in a certain order
I'm thinking I'm missing something because if it were so, almost all code in existence is already an anti-pattern.
2
 
No, that's OK, with some limitations (I thought that was a class at first).
 
ah, so this would be bad:
void foo()
{
  using(var bar = new Bar())
  {
    bar.dothis();
    bar.dothat();
    bar.doThisToo();
  }
}
 
Horrible.
public class C
{
    public void Foo()
    {
        Do1();
        Do2();
        Do3();
    }

    private void Do1();
    private void Do2();
    private void Do3();
}
That's OK.
 
1:35 PM
makes perfect sense now
 
Your example is not.
 
9
A: Is it bad to have a Sub made up of nothing but calls to other Subs?

Mathieu GuindonIf you posted your actual real code on CR, you'd get a much more helpful & meaningful answer. From a design standpoint, what you've got is a "coordinator" whose role is to invoke other procedures in a specific order, which isn't bad in itself. From a pragmatic point of view, what you've got is ...

 
The goal being to not leak the internal implementation details of the class, or as in the linked CR SO post, introduce temporal coupling.
Thanks!
 
@MathieuGuindon Thanks. Guess there's some refactoring incoming. :)
I've been doing exactly that (stringing together Sub calls) and was thinking that it didn't feel exactly right. However I was not so sure how (and why exactly) to transform the subs into functions. Guess I'll give it a go now.
 
> I fixed one warning. Then another, and on reading I see the first has reverted to the pre-fix state.
Example:
Manually edit "space" to "spacetoken". Then click Fix for the "first" hint.
*even if you save after the edit*
But if after the edit, I click Refresh, the edit sticks.
So ... after each Fix, shouldn't you automatically Refresh?

`
Option Explicit

'test for Fix regression
Sub testFix()
Dim first As Integer
Dim space As String
'3 issues found.
'Suggestion: Project name i
 
1:43 PM
@Inarion IMPOV, if there is no state to maintain, a function/sub is a good enough. But if you have to have a state (for example, a open file, a database table, whatever), encapsulating that state into its own class means that it's no longer part of global state and thus you know that the state itself is "scoped" which means you can manage it better than if you allowed it to pollute the global state.
 
@this There is a state to maintain, yes. The last thing I did was a version checking, backup generating update routine for the DB backend. So there's a couple of things to check and some values to store until it finished.
 
@Inarion then it's probably a better candidate for a class, not just a function.
 
And it's almost layed out like a class. It just felt a little to big/multi-purpose to put in into a single class. And I've not yet figured out what parts would warrant being put into a class of their own. :)
 
1:46 PM
Even if you ultimately end up doing nothing more than Set foo = New Foo: foo.DoIt();, that would allow you to isolate the state.
Gotcha. Yeah, that's normal, actually.
A big part of why a good IDE is essential; you need it to make refactoring easier.
 
@this That's a good point, yes. And that's exactly how it's working. :D
 
Otherwise, there's no payoff for refactoring and just risks which means they end up sucking up with the bad code because "it's working"
 
Big risk right there. I agree.
 
> If RD is modifying the code, it should re-parse automatically. If you are modifying the code and then tell RD to make another change, then you have RD working off a stale parse tree. There's really nothing we can do about this, it's always been like this.
 
@Duga well, not necessarily.
We now are listening to the keypress, no?
Set a flag that a parse tree is potentially stale after a keypress has been pressed? (I guess there's also the mouse operations but #babysteps).
we can then use that flag to warn that a reparse is needed before, or disable the refactoring.
 
1:52 PM
> That said, at this point we should be able to have a quickfix or refactoring first verify whether the module has been modified since the parse tree was built, and abort (?) or re-parse (?) before proceeding.
 
@this no, just get the contenthash and compare to what's cached
 
better
 
@this Do you, by any chance, know of some kind of library or anything similar for Access that deals with collapsible form elements? At some point in the past I was needing something like that and as I couldn't find anything useful on the net, I was implementing my own collapsibles. And now I wonder if it would be worth it to post it to CR. (As I was more than happy to find @MathieuGuindon 's list and dict classes there, among others.)
 
Collapisble like an accordion?
 
yeah
 
1:54 PM
Pretty sure that if there were, they'd be for-fee, and provided as an activex control
the only one that comes OOB is when you use datasheets which is kind of limited.
but if you want to use continuous form or just a block of controls, the tab control would be the closest thing OOB, but not truly collapsible.
 
yeah, datasheets weren't all that useful in my specific situation
 
that would be an example of third-party activex control that might let you do what you need: exontrol.com/products.jsp
 
@this IMO if the module was changed, then we should change that module's parser state to Pending - doing that would change parser state to Pending, which would cause all state-dependent commands to be disabled. Inspection Results toolwindow needs to disable its fixes (and navigation?) when parser state isn't Ready
 
not cheap, and not pain-free, though. :\
 
the way I've implemented it, you define any control as bounding box that will hold all controls to be collapsed and initialize the class with bounding box and an actuator control (to expand/collapse). Then you'll need to add one line to the actuator's on click event and it's all working.
 
2:01 PM
@Inarion Clever. Just curious - why not use page break?
 
> Just window title bar, buttons, empty search box.

Click Ready, see a little change .. now I can resize the window to see the code.

Restart Excel, Code Explorer looks OK. Might be just a first-time problem.
 
@MathieuGuindon Hm.. I also wonder if the quickfix action itself needs to be "busy"?
 
@this I'm not sure, actually. I first have to find out how they work and what they do. :D
 
IIRC, someone posted a trick using the page break as a way to divide the section, and by toggling the visible property (note that it won't show on the property sheet but it does have that property), you can achieve the same effect.
Mind, I never had a need to use it though. I maybe only used it like, once some years ago for an Access report.
 
I see. Could have a similar effect. And if so, that would likely have been much easier than what I did. (At least for a start. Then I expanded the class to support horizontal and vertical collapsing.)
 
2:07 PM
oh yeah, page break definitely won't cut it
it's only good for horizontal
 
So I guess I'll check whether I would get into trouble for posting it and if not, try to find some time to polish it up. (I'm also curious what possible improvements and issues you guys would find.)
 
i hardly think you'll get in trouble.
 
@this might get in trouble with the boss, not with the CR community...
 
@this what do you mean?
.Enabled = false should be good enough, no?
 
@FreeMan ah yeah, that'll matter slightly more. :)
 
2:12 PM
^ indeed!
Pssst!, @MathieuGuindon, I think @M.Doerner deserves a sticky star too, don't you?
 
:thumbsup:
 
> Just as a FYI - the improvement in COM release does not address the ghost process w/ Access after exiting; this still exists.
 
@Duga haz a sad... nice to know y'all are still thinking about it!
 
@MathieuGuindon No, I'm thinking that while quickfix is running, there shouldn't be any parses running. Putting it in a busy state would ensure that no parse is running while quickfix is being executed because it'll be mutating the parse tree.
 
2:14 PM
@FreeMan that's what I meant but did not fully verbalize :D
 
@this I dare you to manage to trigger a parse while a quickfix is running :)
 
@Inarion I've had just enough coffee this morning that I was able to read between the lines. ;)
 
(you're right - it's theoretically not impossible)
 
@FreeMan evidently not for me. :)
@MathieuGuindon Yeah I don't think it might come from user clicking, but who knows. A funny thread switch here and there, and bam! Or an errant reparse request from some piece of code that had no idea what state we are in.
TBH, the busy PR made me realize how little I know about concurrency and threading and how hard it is to architect one.
 
actually, that would be a nice stress-test for the cancellation mechanism. triggering a parse while a quickfix is running would likely skip that [not-yet-modified] module, and then the quickfix runs and triggers a reparse, which cancels the currently-running parse
IOW no harm possibly made
 
2:26 PM
@this LOL. That code is what taught me it.
I'm still far more comfortable with concurrency than most people I know because of it.
Just be glad it's not C++ :)
 
@Hosch250 Indeed. Then I'd have to deal with all the memory leaks. :\
(assuming I managed to merely shoot my feet off, rather than my head)
 
You know, people are always talking about population control over here. Why in the world are they promoting not texting and driving then?
You'd think texting and driving would help...
 
2:44 PM
Maybe they don't want to be personally included in the random control factor.
 
2:58 PM
0
Q: VBA, writing to each cell leads to slow code

excelguyWhen I run my code, I get excel not responding error at this sub as I step through the code, more specifically the write portion of this code. Can anyone help optimize this? I think because the loop is writing so many records cell by cell (50k) records its causing my excel sheet to not respond. ...

 
Two comments regarding the quickfixes and reparsing: first, it can do harm if you swap out the rewriter under the nose of the quickfix, in particular if you do it exactly at the moment when it gets accessed. Second, some quickfixes use refactorings that trigger a reparse themselves.
 
I wonder if we should make it so that taking a rewriter will require entering the busy state. That way, a lock is held as long as a rewriter is alive.
That hides the implementation details from the quickfix & anything else that needs a rewriter while guaranteeing that rewriter won't end up working off stale parse trees. Right?
I guess that implies only one rewriter can be provided at any given time. I don't know if that is a valid assumption.
 
I'm wondering whether we can start merging a few of the currently open PRs.
 
btw my internet has been down at home, since 06/15... ISP tech coming today
 
soo .. I assume that means since Friday?
 
3:10 PM
yeah
they changed something and the modem just died
 
lol.
 
A simple way to implement this would be to return a DisposalActionContainer around the rewriter that manages the suspension.
 
That's always fun! I guess I'll quit complaining that my speed's been really slow. At least I still have some tubes...
 
@M.Doerner Why not just make the rewriter itself IDisposable?
@Vogel612 My PRs are not in a state to be merged. I do hope to get to Max's latest recommendations tonight and just perhaps I'll do it right for a change, so it may be merged then. :) The refactoring PR will be a while because of lot of tests I've broke. :\
 
that PR is also explicitly marked as WIP.
all other PRs are not and they have green checkmarks
 
@Vogel612 True. For Mat's PR, there's the feedback from Max to Do The Right Thing™. I'd rather have that but that's just me. For Mansellan's PR, I haven't reviewed. I'm fine w/ merging yours, however.
 
@this me too, but I couldn't git anything this weekend :(
that said, it can't hurt to merge it and do the right thing later on
except, IIRC the reference to System.Net is still in RD.Core
 
oh, so duck's a web server now? Cool.
 
...
the VersionCheck implementation uses it to send an HttpWebRequest...
 
</badjoke>
 
3:25 PM
> Could you add the extended version information from the logs, please? Thank You :)
 
3:46 PM
@this I just thought of a horrible pun.
If/when I have web servers, I'll name them after spiders.
 
@this The rewriter has to be set while parsing because you need the token source. We do not create a new one each time we hand it out. So, the suspension should be active a much shorter time than the lifetime of the rewriter.
 
@ticker damn, so many UserForm questions today - every single one of them involving default instance and global state
 
@this the duck is a webbed server!
 
bah-dum-tish
 
Thank you! I'll be here until Wednesday. Try the veal, and don't forget to tip your waitress!
 
4:04 PM
A bad joke begets bad jokes.
@M.Doerner Gotcha.
 
that's how it goes...
 
@M.Doerner Just to check - could we hide the suspension implementation by having a method like void Rewrite(TokenSource source, Action RewriteAction), so that suspension is taken as soon as we provide a source and all rewrites will be done in that delegate? Would that be short enough?
 
I was going over a file that used CreateObject("Shell.Application"). Is this creating an instance of the Windows shell?
Trying to get my knowledge correct.
 
IIRC, that's for Shell32 library, so it's actually creating a instance of Windows explorer, basically.
Do note that there is another Shell object for scripting, which is different object altogether. WScript.Shell, IIRC.
 
Scriptable Shell Objects is part of the same domain as your link?
 
4:19 PM
Follow the breadcrumb upward. ;)
 
At the top NavBar both say The Windows Shell > ... > ...
 
yep.
 
Making sure. I'm trying to sleuth out for myself now. I still confuse the documentation.
 
it's useful for automating the windows explorer operations. But the downside is that it's all tied up w/ UI that you might not want.
For example, CopyHere will involve confirmation dialogs that you might not want whenever there's file conflicts.
and even if there isn't a confirmation dialog, there'll be a progress dialog, whether you want it or not.
That's why I said it's basically automating the windows explorer (though the library refers to window "shell")
 
@this So it'd be the same as Task Manager>File>New Task (Run...) and typing in explorer.exe?
 
4:21 PM
almost.
 
Except for the fact you can't see it.
I'm not yet trying to automate any operations. Simply trying to understand what the code was doing.
 
I believe there are some operations that will make it visible, though. So it's not totally invisible.
 
@this You're correct msdn.microsoft.com/en-us/library/windows/desktop/… has Shell32.dll in the requirements section.
 
@M.Doerner I thought I'd posted this earlier, but I never did. Anyway, congrats!
 
4:57 PM
Man...
Exceptions for control flow handling...
 
5:08 PM
@Hosch250 yuck...
 
I know. Brand new, but a senior dev/architect.
 
@Hosch250 Ah. That would explain it :-)
 
I swear I'm as good as or better than everyone here individually, except maybe one/two (both architects also).
@mansellan No, the code is brand new. The dev isn't.
Of course, most/all of them know more in certain parts, but overall...
 
@Hosch250 Yeah I figured it was that way around. The number of "Senior Dev \ Team Lead \ Architects" I've worked with over the years... Maybe 10% of them weren't utterly useless.
 
Whatever. I think one of them is right, that I have to leave before I stagnate.
OTOH, where else will it be better?
MS never contacted me, so...
 
5:15 PM
My last jump improved things hugely
but its entirely luck of the draw
 
One thing good here. They listen when I complain.
 
that's worth a lot
i've worked tons of places that were in utter denial
 
Yep.
 
> When AC is enabled, the yellow texttip that normally shows as soon as you start the argument list for a method no longer appear. To get it, one must type space to get it back only to lose it again when another AC is triggered (e.g. for quoting a string).

As an example:

```
DoIt|
```

typing `(` brings us:

```
Dolt(|)
```

without the intellisense. Typing a space, we get it:

```
DoIt( |)
```

But as soon as we type `"`, we get it AC'd but lost the intellisense again:
 
@M.Doerner The end of the beginning, or the beginning of the end. Either way congrats.
 
5:30 PM
> I've been giving this some thought - currently when AC sets `e.Handled = true`, we swallow the keypress.

I think we could easily tweak the `wParam` to make it look like Ctrl+Space or Ctrl+i was pressed. But sending a space wouldn't be right.
> No, Ctrl+Space would bring up the list of available member, which isn't the same as the yellow text tip that comes up. However, Ctrl+i would be indeed appropriate. For now, it's more important to retain the vanilla behavior, so we should do that at least OOB.
 
@Duga I seem to remember there being a distinct name for that yellow thing but darned if I can remember it.
 
@Hosch250 Having it written in this way is acceptable because everything is private? While the example that @this had bar.DoThis ... is not because the members are already public and passing them to a void returning method achieves nothing additional beside the fact that it's in a method?
 
@IvenBach In a way...
The reason it works when they are private is that they are delegated to implementation details.
That way, the caller doesn't care that there are really just three methods called sequentially.
 
> OBTW, just checked - the official name for that yellow tip is Quick Info.
 
And the implementation has to be right (and hopefully the dev has the specs), so they will call in the right order.
 
5:37 PM
Hadn't thought of it as an implementation detail. It makes sense though.
 
OTOH, when they are public, there is nothing preventing someone from A) calling a subset, and B) calling in the wrong order.
 
^ That's what I knee-jerk saw right off.
 
@Duga so IntelliSense really is just the dropdown list of members
I think "IntelliSense" is yet another thing MS renamed/repurposed over the years.
 
Think about how silly it would be if instead of a single method SaveFile, you had to call OpenFile(), WriteFile(), Flush().
 
@this Anecdotally, that's exactly what you do in C++.
 
5:38 PM
@MathieuGuindon I'm sure it got a bit too broad and then there's lot of people (like me!) misnaming it.
@Hosch250 Correct. But if those were the public methods of a class or API....
 
in VS "IntelliSense" includes the xml-doc summary comments
i.e. what the VBE has in "quick info"
 
and it also exposes different information between design time and debug time, too
 
ooh, right
I use these pins all the time
 
yeah
so really all I want AC to do is to swallow the keypress and emit a ctrl + i
 
> Now the big question is.. what would be the wParam value for Ctrl+i? :smile:
 
5:41 PM
the challenge will be retaining it inside a ""
 
@this good news, that's already solved
 
oh wait, it works.
yeah I thought it wouldn't.
but it still works inside, whew.
@Duga what is the wParam in this context?
we're talking about the WM_KEYDOWN, right?
so I assume the wParam has to be the VK_CONTROL | 0x49
wait, that can't be a bitmask.
welp, either you send two window messages or you cheat and use something else entirely different. :)
 
no it has to be one
the modifier would be the loword, the key the hiword, or something like that
also... AC is handling WM_KEYDOWN and WM_CHAR
(and it has to)
although, for inline AC only WM_CHAR is relevant
 
well, not seeing how it'd know that a control and i was pressed using the wParam alone.
 
WM_CHAR wouldn't have a message for Ctrl, so we'd need to... crap.
I need to remove WM_CHAR handling
 
5:52 PM
they aren't bitmask. 0x11 for VK_CONTROL and 0x49 for i, which adds up to 5A.
that'd be the Z key
 
I didn't say that
 
TBH, I'm not seeing a separate place for modifier as it should be.
 
I'm saying you have 00000000 00000000 and 00000000 00000000 making up the wparam
 
hm.
 
@Hosch250 I'm debating that myself. I've not been looking because of the autonomy I have for learning everything I've been able to learn from it. If I'm still limbo-status-no-work again I'll fill it with RD and C#.
 
5:54 PM
right? it's an int32?
 
wParam

    The virtual-key code of the nonsystem key. See Virtual-Key Codes.
 
which WM are you looking at?
 
One'd thunk that they would say that there's a hi/lo word here. This indicates nothing.
WM_Keydown
 
hmm ok I'm wrong
 
5:54 PM
the lParam would have the modifier key then, no?
 
@IvenBach My contract says I can't really do that, but my boss said I can.
The contract is in writing, so I guess it takes precedence.
 
Yep.
 
not according to the documentation, unless I misread
WM_CHAR doesn't seem much better, either
 
wtf, the modifier key has to be somewhere
 
but we have this paragraph....
Because there is not necessarily a one-to-one correspondence between keys pressed and character messages generated, the information in the high-order word of the lParam parameter is generally not useful to applications. The information in the high-order word applies only to the most recent WM_KEYDOWN message that precedes the posting of the WM_CHAR message.
 
5:56 PM
yeah I only picked up WM_CHAR because it was crystal-clear what the printable character was
 
does WM_... stand for anything?
 
vs WM_KEYDOWN, which doesn't quite reliably map to Keys
 
windows message
 
@IvenBach Windows Message
 
Thanks.
 
5:57 PM
yeah it's strange. I would expect the modifier to be in their own container somehow
a parameter, a high word, whatever
otherwise, we have no way of knowing that we're dealing with a ctrl + i, not Z
 
how can we do keyhook hotkeys without the modifiers :(
 
i think the thing is that it's low level
 
@this yeah no, it's definitely not that
 
@MathieuGuindon I think you can't just listen for the CTRL key.
You listen for the I key and see if the CTRL flag is set?
 
you will get messages for Ctrl, followed by I
 
5:58 PM
hmm
 
Trying to follow your conversation. What's the difference with wParam and WM_CHAR?
 
which means you have to transmit two window messages
 
so we can have a Stack<Keys> PressedModifiers
 
That's how you do it in the browser.
 
I think so yes. We need a stack.
 
5:59 PM
@MathieuGuindon Isn't there a CTRL flag on the I key?
 
NAFAIK, Hosch.
 
OK.
 
@IvenBach All window messages run with two parameters, wParam, and lParam
 
the WM_CHAR message's wParam gives us the literal printable char
 
for each type of window message, the wParam and lParam has different meaning
 
00:00 - 18:0018:00 - 00:00

« first day (1473 days earlier)      last day (1707 days later) »