Creating Custom User Control (Not getting the focus back)
Hi, I have created a user control (VB6) with an OCX to view PDF files and with two buttons. But when a form containing that control (Custom User Control) opens, and while closing, I am not getting the focus back to the parent form. But if I use the OCX(PDF viewer) in a normal form it self, its giving me the focus back to the parent form. If a custom user control is containing that OCX control, I am not getting the focus back? Any suggestions? Will it be a bug with the OCX control? Or is there any thing to do with the focus while creating a custom user control? But the reason for my question is, I added another OCX, it works perfectly. Any suggestions.
Re: Creating Custom User Control (Not getting the focus back)
Can you just set the focus back to the parent form when the secondary form closes (the form with your custom control containing the PDF viewer control)?
Re: Creating Custom User Control (Not getting the focus back)
Say Crazy,
This is some other code I stumbled across while looking for something else. This is probably WAY overkill, but it'll certainly get it done. This code can even set the focus onto other apps, if you know their hWnd values.
Code:
Option Explicit
'
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function LockSetForegroundWindow Lib "user32" (ByVal uLockCode As Long) As Boolean
Private Declare Function AllowSetForegroundWindow Lib "user32" (ByVal dwProcessId As Long) As Boolean
Private Declare Function ShowWindow Lib "user32" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Const LSFW_LOCK As Long = 1
Private Const LSFW_UNLOCK As Long = 2
Private Const ASFW_ANY As Long = -1
Private Const SW_SHOWMAXIMIZED = 3
Private Const SW_SHOWNORMAL = 1
Private Const GWL_STYLE As Long = -16
Private Const WS_MAXIMIZE = &H1000000
'
Public Sub ForceWindowFocus(ByVal hWnd As Long)
' You should really make sure the window is visible and enabled before this is called.
LockSetForegroundWindow LSFW_UNLOCK ' Unlock setforegroundwindow calls
AllowSetForegroundWindow ASFW_ANY ' Allow setforeground window calls
If WindowIsMaximized(hWnd) Then
ShowWindow hWnd, SW_SHOWMAXIMIZED
Else
ShowWindow hWnd, SW_SHOWNORMAL
End If
SetForegroundWindow hWnd
LockSetForegroundWindow LSFW_LOCK ' Lock other apps from using setforegroundwindow
End Sub
Public Function WindowIsMaximized(hWndOfInterest As Long) As Boolean
WindowIsMaximized = ((GetWindowLong(hWndOfInterest, GWL_STYLE) And WS_MAXIMIZE) = WS_MAXIMIZE)
End Function
Re: Creating Custom User Control (Not getting the focus back)
Suppose you don't own the source code for that PDF ocx? Out of curiosity. If that ocx was placed in a picturebox on the form, does it perform as expected? Last but not least, with usercontrols, sometimes (not often) the answer to the question is that it works when compiled but not when uncompiled (or vice versa)
And can you be more specific regarding the focus? I'm assuming the pdf file is opened in a separate window, not within some embedded window within your project. If so...
1) Which window is getting focus when pdf is closed? Can you describe the scenarios better?
2) When your form was getting focus back, did it do this if you had other windows stacked between your form and pdf window?
Last edited by LaVolpe; Oct 21st, 2014 at 07:19 PM.
Insomnia is just a byproduct of, "It can't be done"
Re: Creating Custom User Control (Not getting the focus back)
LaVolpe, Yes, that's an OCX from a company. Not ours. that's the main issue here. The strange behaviour here is that, when i add that control to a normal form (Form1.frm), and when i run the programme and open that form and close it, It gives the focus back to the application. (Where i was earlier) But at the same time, when I add this to a user control with some other items (OCX control and for an example, two buttons) and then add that custom user control to a form, and run it and close it, it does not give the focus back to the application. Non of the windows or none of the applications are not getting the focus back. That is my problem. I tries it with a timer and checked what is the active foreground window. But that returns an empty string as well. And I tried with compiling, and the result was the same.
I dont know why that works in a form alone and does not work in a custom user control (MyUserControl.ctl)? Any suggessions laVolpe?
Elroy, thanks for that reply too. But then I have to keep track of each hwnd and it will become a mess as this is quite a big project with loads of forms. Otherwise, keeping the parent form (Called form) will be a solution. But not for this one. But I really appreceate your effort. Cheers !!
Re: Creating Custom User Control (Not getting the focus back)
Here Crazy. I cut out a few functions from what I call my AllPurposeWindowsSpy stuff. You should be able to figure out where the focus is going by playing around with these immediately after your code gets back control from closing your form with your custom control with the PDF viewer on it.
If you play around with this in your Form_Terminate event, I believe it'll tell you where the focus went. The function names are hopefully self-explanatory.
Good Luck.
Code:
Option Explicit
'
Private Declare Function GetForegroundWindow Lib "user32" () As Long
Private Declare Function IsWindow Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Declare Function AttachThreadInput Lib "user32" (ByVal idAttach As Long, ByVal idAttachTo As Long, ByVal fAttach As Long) As Long
Private Declare Function GetFocus Lib "user32" () As Long
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function GetModuleFileName Lib "kernel32" Alias "GetModuleFileNameA" (ByVal hModule As Long, ByVal lpFileName As String, ByVal nSize As Long) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hWnd As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch 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 EnumProcessModules Lib "psapi" (ByVal hProcess As Long, lphModule As Long, ByVal cb As Long, lpcbNeeded As Long) As Long
Private Declare Function GetModuleFileNameEx Lib "psapi" Alias "GetModuleFileNameExA" (ByVal hProcess As Long, ByVal hModule As Long, ByVal lpFileName As String, ByVal nSize As Long) As Long
Private Declare Function GetModuleBaseName Lib "psapi" Alias "GetModuleBaseNameA" (ByVal hProcess As Long, ByVal hModule As Long, ByVal lpFileName As String, ByVal nSize As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Const GWL_STYLE As Long = (-16)
Private Const WS_VISIBLE = &H10000000
Private Const GWL_HINSTANCE = (-6)
Private Const PROCESS_ALL_ACCESS = &H1F0FFF
'
Public Function hWndForeground() As Long
' This returns the top level window with the focus.
' This is typically NOT a control.
hWndForeground = GetForegroundWindow
End Function
Public Function hWndOfFocus() As Long
' This returns whatever object (window, control, etc) which has a hWnd and has the focus.
' Typically, this IS a control.
'
' The GetFocus API only works within the current thread, so we must do more work.
Dim foreWindowThread As Long
Dim hwndFore As Long
'
hwndFore = GetForegroundWindow
If IsWindow(hwndFore) = 0 Then Exit Function
'
foreWindowThread = GetWindowThreadProcessId(hwndFore, ByVal 0&)
'
' Make sure we can "see" the focus according to our Thread ID.
If App.ThreadId <> foreWindowThread Then AttachThreadInput App.ThreadId, foreWindowThread, 1&
hWndOfFocus = GetFocus()
If App.ThreadId <> foreWindowThread Then AttachThreadInput App.ThreadId, foreWindowThread, 0&
End Function
Public Function WindowIsVisible(hWndOfInterest As Long) As Boolean
WindowIsVisible = ((GetWindowLong(hWndOfInterest, GWL_STYLE) And WS_VISIBLE) = WS_VISIBLE)
End Function
Public Function WindowClass(hWndOfInterest As Long) As String
Dim r As Long
Dim sClassName As String * 256
r = GetClassName(hWndOfInterest, sClassName, 256)
WindowClass = Left(sClassName, r)
End Function
Public Function ProcessId(hWndOfInterest As Long) As Long
' This process ID is unique to the entire application to which the window belongs.
' A process ID will always be unique for each running copy of an application, even if more than one copy is running.
Dim lProcId As Long
Call GetWindowThreadProcessId(hWndOfInterest, lProcId)
ProcessId = lProcId
End Function
Public Function ThreadId(hWndOfInterest As Long) As Long
' This is similar to the process ID, but some application can be multi-threaded.
ThreadId = GetWindowThreadProcessId(hWndOfInterest, ByVal &H0)
End Function
Public Function hWndOfParent(hWndOfInterest As Long) As Long
hWndOfParent = GetParent(hWndOfInterest)
End Function
Public Function WindowText(hWndOfInterest As Long) As String
' Form or control.
Dim s As String
Dim l As Long
'
l = GetWindowTextLength(hWndOfInterest)
s = Space$(l + 1)
l = GetWindowText(hWndOfInterest, s, l + 1)
If InStr(s, Chr$(0)) Then s = Left$(s, InStr(s, Chr$(0)) - 1)
WindowText = Trim$(s)
End Function
Public Function ModuleFileName(hWndOfInterest As Long, Optional FullSpec As Boolean = False) As String
Dim ModuleName As String * 260
Dim s As String
Dim hInst As Long
Dim r As Long
'
If App.ThreadId <> ThreadId(hWndOfInterest) Then AttachThreadInput App.ThreadId, hWndOfInterest, 1&
hInst = GetWindowLong(hWndOfInterest, GWL_HINSTANCE)
r = GetModuleFileName(hInst, ModuleName, Len(ModuleName))
s = Left$(ModuleName, r)
If App.ThreadId <> ThreadId(hWndOfInterest) Then AttachThreadInput App.ThreadId, hWndOfInterest, 0&
' If it's a self-contained EXE, there will be no module.
If Len(s) = 0 Then s = ExeFileName(hWndOfInterest, True)
If Not FullSpec Then s = Mid$(s, InStrRev(s, "\") + 1)
ModuleFileName = s
End Function
Public Function ExeFileName(hWndOfInterest As Long, Optional FullSpec As Boolean = False) As String
Dim rtn As Long
Dim lProcMods() As Long
Dim sFileName As String * 260
Dim lSize As Long
Dim lRequired As Long
Dim hProcess As Long
Dim hWndOfFormWithFocus As Long
Dim l As Long
'
lSize = 4
ReDim lProcMods(0)
'
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0&, ProcessId(hWndOfInterest))
' Enumerate modules.
rtn = EnumProcessModules(hProcess, lProcMods(0), lSize, lRequired)
' If array is not large enough to hold all results, number of bytes required is in lRequired.
If lRequired > lSize Then
lSize = lRequired
ReDim lProcMods(0 To (lSize / 4) - 1)
rtn = EnumProcessModules(hProcess, lProcMods(0), lSize, lRequired)
End If
' lProcMods() now holds the list of module handles associated with the process.
' The zeroth element is the main program.
If FullSpec Then
rtn = GetModuleFileNameEx(hProcess, lProcMods(0), sFileName, Len(sFileName))
Else
rtn = GetModuleBaseName(hProcess, lProcMods(0), sFileName, Len(sFileName))
End If
ExeFileName = Left$(sFileName, rtn)
rtn = CloseHandle(hProcess)
End Function
Re: Creating Custom User Control (Not getting the focus back)
Elroy, I was really wondered with your code and wow, that is very useful not only in this but also for my learning as well. Thanks again for that.
I think I got a clue now while I was trying your code in my sample application. That is, while I was executing and closing the form which contains that user control with the OCX, that form's form_terminate event does not get fired? Is that the problem this does not gets the focus back?
Re: Creating Custom User Control (Not getting the focus back)
Hmm, interesting. I'm looking into that, but in the meantime, are you showing this form for viewing PDF's modally? If so, I've got another idea.
In fact, if you're showing it modally, rather than messing with the form_terminate event, right after the "frmPdfForm.Show vbModal" command, use my routines there and see if you can figure it out. It's a bit tricky because you'll have to gather all the information you want in code before doing a MsgBox because that'll get the focus. However, if the problem is in the IDE as well, just use the Debug window.
I'm still looking into the form_terminate event. It's not behaving as I thought it did. Apparently, it only fires when the program ends, and then it fires for all forms that were opened. I've used that event very little, but let me explore a bit more.
Re: Creating Custom User Control (Not getting the focus back)
Ok, the form_terminate event it just weird. Let's forget that idea.
Here's another idea. It's a bit weird, but I've had to do this for similar problems. If you just hide (Me.Hide) your PDF form, you should (hopefully) see the same problem that you were having when you unloaded it. Here's my idea (just for figuring out what's happening):
1) Put a timer on the PDF form, and set its interval to zero (disabled).
2) Put an extra button on the PDF form and put this code in it:
Me.Hide
Timer1.Interval = 500
Timer1.Enabled = true
3) Now, down in that timer's event do this:
Timer1.Enabled = false
... and also play around with the API calls I gave you to figure out where the focus is.
You sure you don't want to use my ForceWindowFocus procedure? :P
But anyway, using the timer (and giving it .5 seconds, which is forever in computer time), the focus should change and then you can figure out where it is.
Re: Creating Custom User Control (Not getting the focus back)
From similar problems I've wrestled down in the past, I can give you some possibly helpful ideas.
I know there's a bit of a difference between the window with the focus and the active window. There are actually two separate API calls for it. It gives me a headache to try and sort out what the difference is, and they're almost always the same. However, in rare instances, they're not.
That dumb Forms20.ocx control had a problem like that. That's why I've LONG abandoned that control for any practical use. When the Focus and the ActiveForm got split, it did nothing but cause problems.
Also, it's not suppose to happen, but the "Hidden" property of a form is also independent from either the Focus or Active properties. Technically, it's possible for a hidden form to have the focus and/or be active. Again, it's not suppose to happen, and Windows should toss the focus aside (giving it to something else) when a form is hidden, but buggy software (not really VB6, but C or C++ software) can get this confused.
Personally, I think your PDF viewer OCX is buggy. If it were me, I'd use the Adobe Acrobat Reader to do it, and just ShellExecute to the Adobe Reader to show my PDF files. In fact, I do precisely that all over the place in the main program that I'm involved with these days.
Code:
Private Sub cmdOpenFirstFoundPDF_Click()
Dim s1 As String
Dim s2 As String
Dim rtn As Long
'
' Attempt to find PDF in the encounter folder.
s1 = EncounterPath & "*.pdf"
s2 = Dir$(s1)
If Len(s2) = 0 Then
MsgBox "No PDF found in this encounter folder.", vbCritical, App.Title
Exit Sub
End If
'
' Open the PDF.
s1 = EncounterPath & s2
rtn = ShellExecute(0, "Open", s1, &H0&, &H0&, SW_SHOWNORMAL)
End Sub
EncounterPath in the above returns a certain folder, and you'll have to sort that for yourself. Also, you'll need the ShellExecute API declaration to use this. Also, it assumes that the Adobe Reader is the default application for PDF's. Actually, many of the workstations that use this software have either Adobe Acrobat Standard or even Adobe Acrobat Pro installed on them, and that's what would open the PDF.
Re: Creating Custom User Control (Not getting the focus back)
Let say that first stage is a user contol in a form. And we can say that 2nd stage is a closed type control (an ocx) contained in a user control
When you are in the first stage, in a user control, you miss the "visible" property...Wou don't now if your control is visible or not. What you know is events that produced from some source. We can't set focus a control that we don't have it as visible. So you can get the parent object, the form and set a reference to it.So now you can read if we have a visible user control and then we can set the focus. So now we came to second stage. The ocx ask from parent to see if it is visible...but...the user control has no such property.
So if we wish to "hack" the system we have to provide a visible property...
Now from the form visible is the right one not the fake (the property that has the superclass of usercontrol). But from ocx...the property visible is the fake one (I have two user contols, in Scrollio a remake from dilettante, and I make a small example..the inner control by using usercontrol.parent.visible show the usercontrol fake property. From form the scrollio1.visible is the known visible property not the fake one.
Public Property Get Visible() As Boolean
'
End Property
Public Property Let Visible(ByVal vNewValue As Boolean)
'
End Property..
So copy that put a stop to each, and look what happen...maybe the OCX use the visible property.
Also do that for TOP and LEFT...
Last edited by georgekar; Oct 22nd, 2014 at 01:52 PM.
Re: Creating Custom User Control (Not getting the focus back)
Hi georgekar, thank you verymuch for your reply. It was a very interesting point. Today I played around with that idea. But after inserting,
Public Property Get Visible() As Boolean
'
End Property
Public Property Let Visible(ByVal vNewValue As Boolean)
'
End Propert
While setting the visibility (DisplayScan.Visible = False) [Assume DisplayScan is the user control] I made a break point in both places. But non of them were fired. Is that because of a default property? I had the same issue with Width and Height as well. Is there a different way of writing those default variables in a user control? This is how I made that attempt.
Code:
Private pbVisible As Boolean
Const pbVisibleDef = True
'Visible --------------------------
Public Property Let Visible(ByVal bVisible As Boolean)
pbVisible = bVisible
VisibleSet bVisible
PropertyChanged "Visible"
End Property
Private Sub VisibleSet(ByVal bVisible As Boolean)
UserControl.ImageViewer.Visible = bVisible
UserControl.ImgEdit.Visible = bVisible
End Sub
Public Property Get Visible() As Boolean
Visible = pbVisible
End Property
' Write Properties ---------------------
Private Sub UserControl_WriteProperties(pb As PropertyBag)
pb.WriteProperty "WidthC", plWidthOfControl, plWidthOfControlDef
pb.WriteProperty "HeightC", plHeightOfControl, plHeightOfControlDef
pb.WriteProperty "Tag", psTag, ""
pb.WriteProperty "Visible", pbVisible, pbVisibleDef
End Sub
'Read Properties ---------------------
Private Sub UserControl_ReadProperties(pb As PropertyBag)
plWidthOfControl = pb.ReadProperty("WidthC", plWidthOfControlDef)
WidthOfControlSet plWidthOfControl
plHeightOfControl = pb.ReadProperty("HeightC", plHeightOfControlDef)
HeightOfControlSet plHeightOfControl
psTag = pb.ReadProperty("Tag", "")
pbVisible = pb.ReadProperty("Visible", pbVisibleDef)
VisibleSet pbVisible
End Sub
Re: Creating Custom User Control (Not getting the focus back)
Elroy, I appreciate your kind advice. here I am displaying the PDF itself on the form and when the user double clicks on it, I am using your method to open the file. Earlier I used AcroPDF.dll as well. But they had stopped the service wiTH VB6. So had to to move to a custom one and the company went for a software company called Viscomsoft (http://www.viscomsoft.com/products/i...pro/index.html) and bought that PDF viewing OCX. It works perfectly with normal MDI forms. This buggy thing appears only in custom user control containing forms only. But really appreciate your thought. Cheers!!
Re: Creating Custom User Control (Not getting the focus back)
Hey, I definitely know where you're at. You've just got an idea in your head as to how it should work, and the dumb thing just won't do it. I'm totally one to beat my head on the wall until I can get it to work EXACTLY like I want. Without having a copy of your OCX, I'm sort of out of ideas on this one though. I do wish you the best of luck.
Just one last idea. You said they were using the AcroPDF.dll. Can't they just keep using that one? I suppose the problem with that is that it would ultimately quit working with the enhancements they keep making to the PDF standard.
Re: Creating Custom User Control (Not getting the focus back)
Elroy, you are one of da bests i have ever met on a forum. Respect for that. If you have a free time only, can you check this one for me. But if you have time only. When you go to this link (http://www.viscomsoft.com/products/i...pro/index.html) you can download the trial ocx containning exe (it will ask for licence code when a form is there more than 3 mins or more. But that's fine)and here I have made a sample project to demonstrate the fact. If you have a time only can you please have a look on that. But if you don't have a time, thats absolutely fine Elroy. Thanks for everything. Cheers!!
PS : AcroPDF is not a trusted solution Elroy. If they keep changing, I've to go for more solutions. That's why I was looking for a permenant solution for the company.
Re: Creating Custom User Control (Not getting the focus back)
Hey Crazy,
I'm gonna splash around in some of the other forum threads for a bit right now, and maybe get some paying work done, but who knows what I'll do. We'll see. *smiles* You take care.
Re: Creating Custom User Control (Not getting the focus back)
Ok Crazy,
I downloaded the control and installed the demo and took a look. I'm still not sure what it's doing, although I did mess with it a bit. However, I think you're doing too much work. Let me make some suggestions. You're making a custom user control with a custom user control on it. This shouldn't be a problem, but I don't see why you need to do it this way.
Why not just start a new form (not a user control) and put the ImageViewer on it. Also, put whatever "Next" and "Prev" buttons you want on this form. I tried it that way, and everything seems to work fine (at least with the focus going where it's suppose to). That form will be what you use to show your PDF files.
Also, designing complete custom user controls can be a pain-in-the ass, and I see that you haven't even started passing your events, properties, and methods through to the custom control you're developing. I don't know if you're familiar with developing custom user controls or not. If you're not, I'd stay away from it until it's truly necessary (which it really doesn't seem to be in this situation).
Also, I see that you went to a lot of trouble to show your forms. Here's what I did to your code and it does exactly the same thing:
Code:
'Forms.Add "FormWithImageViewerUserControl"
'Dim frm As Form
'Set frm = Forms(Forms.Count - 1)
'Load frm
'frm.Show
' Crazy, this does all the above in one line, and no need for frm variable.
FormWithImageViewerUserControl.Show
Also, I noticed that you didn't have an Option Explicit as your first line. PLEASE use Option Explicit. In the IDE, on menu, under Tools/Options, you'll find the option on the "Editor" tab: "Require Variable Declaration". That'll put Option Explicit in every new module you start.
Also, I did figure out how to use the functions I supplied above. I showed your FormWithImageViewerUserControl modally. When it terminated I still had the same problem. Therefore, I could put code immediately after it and see where the focus went. It was still in VB6, but somewhere quite unknown. Here's the code I used:
I did it both in the IDE and also compiled. I used the Debug window while in the IDE, and MsgBox as compiled. Your problem exists in both situations. Again, forget designing your own custom control, and just put the ImageViewer directly onto a form, with that form being a special form you use for showing your PDFs.
Let me know if that works for you, and how it's going.
Re: Creating Custom User Control (Not getting the focus back)
Elroy, first of all many thanks for the effort. Let me tel you the story. Here I've made the sample application to send to the company to demonstrate the issue. The Imageviewer is not the only conntrol im my custom user control. Its just here to demonstrate the issue only I do have another control alongside with this for TIF display and TIF edit in the same control. Then depending on the file, I am displaying the relevent control. But here for the demonstration, I've removed them and just placed the ImageViewer only in the user control (With Two Buttons). The TIF editing and the viewing control is also an OCX. But no pain at all with them ones. The problem occured on this buggy control Elroy. And I didn't include any code on my custom user control as it's going to be more complex. I just wanted to show that, it's not getting the focus as normal on a user control. (Other OCX's do - My TIF control is also an OCX and When I put that only in the User control, it works absolutely fine) In my actual programme, I've added all the codes for the user control to work with events and all the stuff. But again n again, thanks alot for your time and for your hard work Elroy. And thanks for those valuable advices on coding. I really appreciate those kind words. Definietley I'll use these methods from next time. Cheers!!!
Re: Creating Custom User Control (Not getting the focus back)
I use this code in M2000 Interpreter in glist control. You get the VISIBLE property, working for indexed and not indexed controls (so now you know how to do for other properties), and a helper function GetStrUntilB(). As you see with this function we can extract data folded to anything.
Code:
Public Property Let Visible(ByVal rhs As Boolean)
Dim mm$, mo As Control, NM$, cnt$, p As Long
mm$ = UserControl.Ambient.DisplayName
NM$ = GetStrUntilB(p, "(", mm$ & "(", True)
cnt$ = GetStrUntilB(p, ")", mm$, True)
On Error Resume Next
If UserControl.Parent Is Nothing Then Exit Property
If Err.Number > 0 Then Exit Property
If cnt$ <> "" Then
Set mo = UserControl.Parent.Controls(NM$).item(CInt(cnt$))
Else
Set mo = UserControl.Parent.Controls(NM$)
End If
mo.Visible = rhs
End Property
Public Property Get Visible() As Boolean
Dim mm$, mo As Control, NM$, cnt$, p As Long
mm$ = UserControl.Ambient.DisplayName
NM$ = GetStrUntilB(p, "(", mm$ & "(", True)
cnt$ = GetStrUntilB(p, ")", mm$, True)
On Error Resume Next
If UserControl.Parent Is Nothing Then Exit Property
If Err.Number > 0 Then Exit Property
If cnt$ <> "" Then
Set mo = UserControl.Parent.Controls(NM$).item(CInt(cnt$))
Else
Set mo = UserControl.Parent.Controls(NM$)
End If
Visible = mo.Visible
End Property
Private Function GetStrUntilB(pos As Long, ByVal sStr As String, fromStr As String, Optional RemoveSstr As Boolean = True) As String
Dim i As Long
If fromStr = "" Then GetStrUntilB = "": Exit Function
If pos <= 0 Then pos = 1
If pos > Len(fromStr) Then
GetStrUntilB = ""
Exit Function
End If
i = InStr(pos, fromStr, sStr)
If (i < 1 + pos) And Not ((i > 0) And RemoveSstr) Then
GetStrUntilB = ""
pos = Len(fromStr) + 1
Else
GetStrUntilB = Mid$(fromStr, pos, i - pos)
If RemoveSstr Then
pos = i + Len(sStr)
Else
pos = i
End If
End If
End Function
Re: Creating Custom User Control (Not getting the focus back)
For your experiment: You place an ocx control as thatcontrol in your user control as YourControl. So You have to see if thatcontrol need to see if it visible. But how can this done? I post above my code to what I do for that. I get an object mo..(m)y (o)bject...as YourControl because i need a reference to the created object, not to class code. Visible property from mo, is the actual property, of the user control. The ocx when reference to parent see the code, and found visible in the code, so we need to link that code with the actual object, and we do that with mo (mo is just a reference, and when the last reference break, then the object...die...but that can be done from an unloading from a form. Because mo is a local var, after the end of the property's code erased, and erased the link together.)
We have always an error when "no client" exist, when the form closed we can't refer to parent. So we need to check if parent is nothing or not.
Re: Creating Custom User Control (Not getting the focus back)
Hey Crazy,
I do now have a better picture of what you're doing, but I still don't see a reason that you can't just put together a specialized form to do your work (with no need for developing your own custom user control). I've written my fair share of custom user controls (in fact, I just posted a Unicode textbox in the codebank), but I can tell you my thinking for when a custom user control is appropriate:
If I have a situation where I need four or five (or 40) controls on a single form that do something beyond what the standard controls do. For instance, I develop software to help physical therapists do examinations. I have what I call the DegreeBar custom control. Initially, it looks like a TextBox. However, when you click it, a vertical slider bar pops up and allows you to slide it to specify how many degrees (for some joint angle) should be placed in the textbox. The control has properties for min-degrees, max-degrees, typical-degrees, etc. Here's a picture of it:
You click any of the textboxes and the (orange) slider pops up for them.
However, my important point is that there are MANY of these controls on a single form.
Let me outline another situation. This same application has MANY places where reports can be printed. Everytime this happens, I give the user an option to print the report, export the report, or both. I have a special little form just for doing this that's used in MANY places throughout the code:
Here, no need for a custom control because this specialized form suffices perfectly. This print/export form isn't as sophisticated as your PDF viewing form would be but it sounds like the level-of-function is about the same (with no need for multiple copies of its functionality on another form).
Crazy, I'd be motivated to mess with your project some more to see where the focus is going, but only if it makes sense for what you're trying to do.